![在 nginx 中,内部重定向时重写或内部重定向循环](https://linux22.com/image/702439/%E5%9C%A8%20nginx%20%E4%B8%AD%EF%BC%8C%E5%86%85%E9%83%A8%E9%87%8D%E5%AE%9A%E5%90%91%E6%97%B6%E9%87%8D%E5%86%99%E6%88%96%E5%86%85%E9%83%A8%E9%87%8D%E5%AE%9A%E5%90%91%E5%BE%AA%E7%8E%AF.png)
我正在尝试让重写规则适用于 nginx 和 Wordpress。重新启动 nginx 后,我尝试访问该网站并收到 IS 500 错误页面。日志文件显示:
*1 rewrite or internal redirection cycle while internally redirecting to "/index.php"
我很困惑,因为所有教程中(甚至是使用 nginx 设置重写规则的 Wordpress 文档中)都是这样告诉你的:
try_files $uri $uri/ /index.php?$args ;
以下是整个服务器块:
server {
listen 178.79.134.35:443 http2;
listen [::]:443 http2;
server_name foo.co.uk www.foo.co.uk cdn.foo.co.uk;
ssl on;
ssl_certificate /home/test/conf/web/ssl.foo.co.uk.pem;
ssl_certificate_key /home/test/conf/web/ssl.foo.co.uk.key;
error_log /var/log/apache2/domains/foo.co.uk.error.log error;
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args ;
proxy_pass https://178.79.134.35:8443;
location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
root /home/test/web/foo.co.uk/public_html;
access_log /var/log/apache2/domains/foo.co.uk.log combined;
access_log /var/log/apache2/domains/foo.co.uk.bytes bytes;
expires max;
try_files $uri @fallback;
}
}
location /error/ {
alias /home/test/web/foo.co.uk/document_errors/;
}
location @fallback {
proxy_pass https://178.79.134.35:8443;
}
location ~ /\.ht {return 404;}
location ~ /\.svn/ {return 404;}
location ~ /\.git/ {return 404;}
location ~ /\.hg/ {return 404;}
location ~ /\.bzr/ {return 404;}
include /home/test/conf/web/snginx.foo.co.uk.conf*;
}
有人有什么建议吗?我甚至尝试了一些更混乱的方法,但还是出现了同样的错误:
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?q=$1 last;
break;
}
我做了一些调整,所以它确实通过了
location / {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/test/web/foo.co.uk/public_shtml$fastcgi_script_name;
include fastcgi_params;
try_files $uri $uri/ /index.php?$args ;
proxy_pass https://178.79.134.35:8443;
location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
root /home/test/web/foo.co.uk/public_shtml;
access_log /var/log/apache2/domains/foo.co.uk.log combined;
access_log /var/log/apache2/domains/foo.co.uk.bytes bytes;
expires max;
try_files $uri @fallback;
}
}
更新2:按照建议,我知道一个location ~ \.php$ { }
块是如何包裹它的。所以它看起来像:
location / {
proxy_pass https://178.79.134.35:8443;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME home/test/web/foo.co.uk/public_shtml$fastcgi_script_name;
include fastcgi_params;
}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
root /home/test/web/foo.co.uk/public_shtml;
access_log /var/log/apache2/domains/foo.co.uk.log combined;
access_log /var/log/apache2/domains/foo.co.uk.bytes bytes;
expires max;
try_files $uri @fallback;
}
try_files $uri $uri/ /index.php?$args ;
}
但我现在收到一个错误:
111:连接被拒绝)连接到上游时,客户端:81.174.134.133,服务器:foo.co.uk,请求:“GET /wp-admin/HTTP/2.0”,上游:“fastcgi://127.0.0.1:9000”
在 Google 上查找,人们建议测试端口 9000:
root@com:/home/# telnet localhost 9000
Trying ::1...
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
所以它似乎无法访问它。不过我有点困惑,因为防火墙设置为允许端口 9000:
ACCEPT tcp -- anywhere anywhere tcp dpt:9000
更新2:根据建议,我尝试过:
netstat -nltp|grep 9000
...但是没有结果。如果我查看,我可以看到 php-7.0-fpm 已安装并正在运行(据我所知);
root@com:~# service php7.0-fpm status
â php7.0-fpm.service - The PHP 7.0 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php7.0-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2017-04-12 12:06:48 UTC; 18h ago
Process: 3560 ExecStartPre=/usr/lib/php/php7.0-fpm-checkconf (code=exited, status=0/SUCCESS)
Main PID: 3800 (php-fpm7.0)
Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
CGroup: /system.slice/php7.0-fpm.service
ââ3800 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
ââ3872 php-fpm: pool www
ââ3882 php-fpm: pool www
Apr 12 12:06:43 com.x.com systemd[1]: Starting The PHP 7.0 FastCGI Process Manager...
Apr 12 12:06:48 com.x.com systemd[1]: Started The PHP 7.0 FastCGI Process Manager.
我查看了/etc/php/7.0/fpm/php-fpm.conf
,但没有看到任何关于“监听”端口的引用
更新 3:我找到了一篇关于编辑www.conf
文件的帖子:https://github.com/serghey-rodin/vesta/issues/1025
因此,在我的服务器上搜索该内容时,我发现:
/etc/php/7.0/fpm/pool.d/www.conf
然后我评论说:
listen = /run/php/php7.0-fpm.sock
...并补充道:
listen = 9000
...然后重新启动:
service php7.0-fpm restart
现在我可以在netstat
然后我确保我的配置中有这个:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/test/web/foo.co.uk/public_shtml$fastcgi_script_name;
include fastcgi_params;
}
重新启动 nginx,然后 :) 它就复活了!
答案1
在 PHP 项目中使用 Nginx 有两种常见方法:
Nginx 提供静态文件服务,PHP 处理由 PHP-FPM 守护进程完成,并由 Nginx 使用 FastCGI 进行代理
设置专用服务器以获得最佳性能是一种常见的情况,您应该使用它,除非您的应用程序严重依赖 Apache 的某些功能,.htaccess
并且您无法在 Nginx 配置中一劳永逸地写入它。
server {
...
root /home/test/web/foo.co.uk/public_html;
fastcgi_index index.php;
location / { try_files $uri $uri/ /index.php?$args; }
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
access_log /var/log/apache2/domains/foo.co.uk.log combined;
access_log /var/log/apache2/domains/foo.co.uk.bytes bytes;
expires max;
}
}
Nginx 提供静态文件服务,其他所有内容都代理到内部 Apache 守护程序
在这种情况下,PHP 处理由 Apache 的 mod_php 模块完成。设置如下:
server {
...
root /home/test/web/foo.co.uk/public_html;
location / { proxy_pass https://178.79.134.35:8443; }
location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
access_log /var/log/apache2/domains/foo.co.uk.log combined;
access_log /var/log/apache2/domains/foo.co.uk.bytes bytes;
expires max;
}
}
除非您希望 apache 生成严重的 404 页面,否则无需为静态文件添加 fallback 代码。这也可以在 nginx 中使用error_page
指令进行设置。
此外,在这种情况下,请考虑通过普通 HTTP 端口上的环回接口连接到 Apache,以获得更好的性能。应仅在前端 Web 服务器上设置 HTTPS。代理到同一主机上启用 HTTPS 的端口实际上不会给您带来任何好处。
更新:为了举例说明,我在示例中使用了 TCP 套接字连接到 PHP-FPM。但是,互联网上有许多基准测试表明,本地 UNIX 套接字的性能优于 TCP 套接字。对于 Nginx 来说,使用 UNIX 套接字也相当容易:
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
确保检查该文件和相应路径的访问权限。