nginx;如果仅使用 try_files 存在文件,则返回响应代码
Posted
技术标签:
【中文标题】nginx;如果仅使用 try_files 存在文件,则返回响应代码【英文标题】:nginx; return response code if a file exists by using try_files only 【发布时间】:2013-05-17 14:09:34 【问题描述】:自从IfIsEvil 以来,我一直在尝试使用指令try_files
设置配置,以便维护页面与响应代码503 一起显示,对于任何URI 无一例外,即包括php 页面,如果存在维护文件。
我的配置有两个问题:
-
维护页面不显示 php URI。
如果maintenance.html文件存在,则不返回响应码503。
我见过类似的问题[1],[2],但没有一个解决方案只使用try_files
(而不是使用if
指令)并且无条件地提供响应代码为503 的维护页面,如果存在相应的文件。这样的解决方案可行吗?
以下是我当前无法使用的 conf 文件。它不包含 503 响应代码设置,因为我不明白它应该去哪里才能使其按上述方式工作。
worker_processes 1;
error_log /var/log/nginx/error.log debug;
events
worker_connections 1024;
http
include mime.types;
default_type application/octet-stream;
index index.php index.html index.htm;
server
listen 80;
server_name rpi;
root /www;
location /
try_files /maintenance.html $uri $uri/ /index.php?$args;
# pass the PHP scripts to FastCGI server
location ~ \.php$
try_files $uri =404;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
我想我的问题也可以这样表述:try_files
可以用作if
控制结构吗?如果不是单独使用,是否可以根据上述目标与其他指令结合使用,不包括if
指令?
编辑:以下是使用if
的解决方案,我目前正在使用它,将其包含在服务器部分中:
error_page 503 @maintenance;
if (-f $document_root/maintenance.html)
return 503;
location @maintenance
try_files /maintenance.html =404;
【问题讨论】:
【参考方案1】:非常好的问题!但是,除非您调用某种设置正确响应代码的脚本,否则这是不可能的。
仅使用 nginx 且没有 if 的有效解决方案
try_files
directive 仅对最后一条语句执行内部重定向。但是我们可以将它与index
directive 结合起来并强制进行内部重定向。
# This will be the HTML file to display for the 503 error.
error_page 503 /maintenance/maintenance.html;
# Let nginx know that this particular file is only for internal redirects.
location = /maintenance/maintenance.html
internal;
# Any request that starts with the maintenance folder is 503!
location ^~ /maintenance/
return 503;
# Instead of checking if a file exists and directly delivering it we check
# if a certain directory exists and trigger our index directive which will
# perform an internal redirect for us.
location /
expires epoch;
try_files /maintenance/ $uri $uri/ /index.php?$args;
这种方法有什么缺点吗?
实际的 301 重定向到目录,而不是停留在相同的 URL(搜索引擎)。 浏览器缓存 301 重定向可能是一个问题,这就是我将expires epoch
添加到位置块的原因。
其他解决方案?
通过nginx配置文件
与其创建一个 HTML 文件,不如创建一个 nginx 配置文件并简单地重新加载进程?
更好的性能! 更容易理解! 没有副作用!nginx 配置可能如下所示(注意这个if
一点也不邪恶):
error_page 503 /maintenance.html;
location /
include maintenance.conf;
if ($maintenance = 1)
return 503;
try_files $uri $uri/ /index.php?$args;
maintenance.conf
文件的内容:
set $maintenance 0;
如果你想激活维护模式(在你的 shell 中):
echo set $maintenance 1;> maintenance.conf && service nginx reload
更高级的shell朋友 你甚至可以用这个扩展一个初始化脚本,例如 my LSB compliant one 通过替换文件末尾的以下块:
*)
echo "Usage: $NAME force-reload|reload|restart|start|status|stop" >&2
exit 1
;;
使用以下块:
maintenance)
echo "set $maintenance 1;" > /etc/nginx/maintenance.conf && service nginx reload;
;;
production)
echo "set $maintenance 0;" > /etc/nginx/maintenance.conf && service nginx reload;
;;
*)
echo "Usage: $NAME force-reload|reload|restart|start|status|stop|maintenance|production" >&2
exit 1
;;
现在您可以简单地执行以下命令(包括自动完成)进入维护模式:
service nginx maintenance
或以下内容重新投入生产:
service nginx production
带有脚本/PHP文件
另一个非常简单的方法是使用处理它的 PHP 文件。
location /
try_files /maintenance.php $uri $uri/ /index.php?$args;
您的 PHP 文件看起来与您的 HTML 文件一模一样,您只需在其开头添加以下内容(假设 PHP 5.4+):
<?php http_response_code(503) ?><!doctype html>
<html>
<head>
<!-- ... more html ... -->
【讨论】:
以上是关于nginx;如果仅使用 try_files 存在文件,则返回响应代码的主要内容,如果未能解决你的问题,请参考以下文章