我最近一直在为一个 Web 开发客户配置一台新服务器,遇到了一个有趣的问题。该网站的流量相当大,但 CMS 相当繁重,在实时生成页面方面效率低下。当需要直接从 CMS 生成页面时,这会大大减慢页面加载速度。不幸的是,由于多种原因,CMS 与 Apache 绑定,因此通过 nginx 从 Apache 提供页面不是一个可行的选择。此外,CMS 的 Apache .htaccess 文件必然有些复杂和繁琐,因此从 Apache 提供的请求相对较慢。
由于这些因素,我将 nginx 配置为反向代理服务器,并为 CMS 编写了一个插件,该插件会将页面呈现为静态 HTML,并将其存储在合理的特定缓存目录中。我的目的是将 nginx 配置为直接处理缓存文件的请求,从而完全避免使用 apache(更重要的是,避免使用 CMS)。
到目前为止,这个过程进展顺利,我让 nginx 成功提供由 CMS 生成的缓存文件(响应速度很快,只需 25 毫秒,而 CMS 则需要 500 多毫秒),如果缓存文件不存在,则将其传递给 CMS,但有一个例外:主页。出于某种原因,主页位置块似乎根本没有激活。
这是网站配置(匿名):
# reverse proxy config for example.com, serves all non-dynamic files
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/;
add_header "X-Index-0" "block-0";
location ^~ ^(index)?\.?(htm|html|php|asp|aspx)?$ {
try_files /var/www/example.com/cache/index.html @apache;
add_header "X-Index-1" "block-1";
}
location / {
try_files /var/www/example.com/cache/index.html @apache;
add_header "X-Index-2" "block-2";
}
location ~ ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|js|ttf|woff|svg|otf)$ {
etag on;
expires 30d;
}
location ~ ^(.+\.html)$ {
root /var/www/example.com/static-cache;
add_header "X-Cache-Hit" $uri;
try_files $1 @apache;
expires 7d;
}
location @apache {
add_header 'X-Block-Apache' 'block';
proxy_set_header 'Host' $host;
proxy_set_header 'X-Forwarded-From' $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
}
问题是,尽管存在 /var/www/example.com/cache/index.html(通过在文本编辑器中以与 nginx 相同的用户身份打开它来验证),但对网站根目录(example.com)的每个请求都会被路由到 @apache 块。我向每个位置块添加了 add_header 行,试图了解正在激活的位置块及其激活顺序。不幸的是,我收到的响应请求的唯一标头是“X-Block-Apache”,这表明针对网站根目录(以及对索引文件的任何请求)的位置块均未激活。
这种印象因以下事实而得到强化:http://example.com/index.html给我一个“X-Cache-Hit”标头,很明显是由 nginx 提供的(与从 CMS 提供的页面相比,速度大约是 15 倍)。但是,在这种情况下,第一个位置块不应该触发吗?如果访问 example.com 似乎没有触发“location /”块,我该怎么做才能让索引文件从 nginx 正确提供服务?
谢谢您的帮助!
答案1
您try_files
正在尝试加载指定的文件,/var/www/example.com/var/www/example.com/cache/index.html
但该文件不存在。
请记住,您需要指定相对于文档的路径root
。
try_files /cache/index.html @apache;