Nginx的 – 405不允许 – fastcgi超时

我试图设置一个网站使用php 5.6和nginx synology。 该网站是WordPress和一个主题。 处理演示导入时,我们有一个NGINX错误405(不允许)。

这是有点令人沮丧,因为我喜欢当事情正确完成。

我看了php.ini文件和nginx.conf文件。

# Copyright (c) 2000-2016 Synology Inc. All rights reserved. worker_processes auto; #worker_cpu_affinity auto; worker_rlimit_nofile 65535; include conf.d/main.conf; events { use epoll; multi_accept on; worker_connections 1024; include conf.d/events.conf; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log off; #access_log syslog:server=unix:/dev/log,facility=local7,tag=nginx_access,nohostname main; error_log syslog:server=unix:/dev/log,facility=local7,tag=nginx_error,nohostname error; sendfile on; server_tokens off; proxy_request_buffering off; fastcgi_request_buffering off; scgi_request_buffering off; proxy_buffering off; fastcgi_buffering off; scgi_buffering off; resolver_timeout 5s; client_header_timeout 10s; client_body_timeout 60s; send_timeout 60s; keepalive_timeout 65s 20s; client_max_body_size 0; server_names_hash_max_size 8192; ssl_certificate /usr/syno/etc/certificate/system/default/fullchain.pem; ssl_certificate_key /usr/syno/etc/certificate/system/default/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; ssl_dhparam /usr/syno/etc/ssl/dh2048.pem; ssl_prefer_server_ciphers on; gzip_disable "msie6"; gzip_min_length 1000; gzip_types text/plain text/css application/javascript application/json; gzip_vary on; gzip_static on; upstream synoscgi { server unix:/run/synoscgi.sock; } index index.html index.htm index.php; set_real_ip_from 127.0.0.1; real_ip_header X-Real-IP; server { listen 5000 default_server; listen [::]:5000 default_server; server_name _; gzip on; include app.d/alias.*.conf; root /usr/syno/synoman; index index.cgi; ignore_invalid_headers off; include app.d/dsm.*.conf; include /usr/syno/share/nginx/conf.d/dsm.*.conf; include conf.d/dsm.*.conf; location = / { try_files $uri /index.cgi$is_args$query_string; } location ~ ^/volume(?:X|USB|SATA|Gluster)?\d+/ { internal; root /; include app.d/x-accel.*.conf; include conf.d/x-accel.*.conf; } location ~ /webman/modules/(PersonalSettings|ExternalDevices|FileBrowser)/index_ds.php$ { alias /usr/syno/share/OAuth/index_ds.php; default_type text/html; } location ~ \.cgi { include scgi_params; scgi_read_timeout 3600s; scgi_pass synoscgi; } error_page 403 404 500 502 503 504 @error_page; location @error_page { root /usr/syno/share/nginx; rewrite (.*) /error.html break; } location ~ ^/webman/modules/Indexer/ { deny all; } location ~ ^/webapi/lib/ { deny all; } location ~ ^/webapi/(:?(:?.*)\.lib|(:?.*)\.api|(:?.*)\.auth|lib.def)$ { deny all; } location ~ /\. { access_log off; log_not_found off; deny all; } location ~* \.(?:js|css|png|jpg|gif|ico)$ { access_log off; log_not_found off; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { allow all; access_log off; log_not_found off; } } server { listen 5001 default_server ssl; listen [::]:5001 default_server ssl; server_name _; include app.d/alias.*.conf; root /usr/syno/synoman; index index.cgi; ignore_invalid_headers off; include app.d/dsm.*.conf; include /usr/syno/share/nginx/conf.d/dsm.*.conf; include conf.d/dsm.*.conf; location = / { try_files $uri /index.cgi$is_args$query_string; } location ~ ^/volume(?:X|USB|SATA|Gluster)?\d+/ { internal; root /; include app.d/x-accel.*.conf; include conf.d/x-accel.*.conf; } location ~ /webman/modules/(PersonalSettings|ExternalDevices|FileBrowser)/index_ds.php$ { alias /usr/syno/share/OAuth/index_ds.php; default_type text/html; } location ~ \.cgi { include scgi_params; scgi_read_timeout 3600s; scgi_pass synoscgi; } error_page 403 404 500 502 503 504 @error_page; location @error_page { root /usr/syno/share/nginx; rewrite (.*) /error.html break; } location ~ ^/webman/modules/Indexer/ { deny all; } location ~ ^/webapi/lib/ { deny all; } location ~ ^/webapi/(:?(:?.*)\.lib|(:?.*)\.api|(:?.*)\.auth|lib.def)$ { deny all; } location ~ /\. { access_log off; log_not_found off; deny all; } location ~* \.(?:js|css|png|jpg|gif|ico)$ { access_log off; log_not_found off; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { allow all; access_log off; log_not_found off; } } server { listen 80 default_server; listen [::]:80 default_server; listen 443 default_server ssl; listen [::]:443 default_server ssl; server_name _; location ~ ^/volume(?:X|USB|SATA|Gluster)?\d+/ { internal; root /; include app.d/x-accel.*.conf; include conf.d/x-accel.*.conf; } include app.d/www.*.conf; include app.d/alias.*.conf; include /usr/syno/share/nginx/conf.d/www.*.conf; include conf.d/www.*.conf; location = /webman/pingpong.php { rewrite /webman/pingpong.php /webman/pingpong.cgi break; root /usr/syno/synoman; include scgi_params; scgi_pass synoscgi; } location = /webdefault/images/logo.jpg { alias /usr/syno/share/nginx/logo.jpg; } error_page 405 =200 $uri; location ~* \.php$ { include fastcgi_params; fastcgi_index index.php; fastcgi_read_timeout 240; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } error_page 403 404 500 502 503 504 @error_page; location @error_page { root /usr/syno/share/nginx; rewrite (.*) /error.html break; } location ^~ /.well-known/acme-challenge { root /var/lib/letsencrypt; default_type text/plain; } include app.d/.location.webstation.conf*; location ~ ^/$ { if ($scheme = https) { rewrite / https://$host:5001/ redirect; } rewrite / http://$host:5000/ redirect; } } include conf.d/http.*.conf; include app.d/server.*.conf; include sites-enabled/*; } 

我在互联网上search了很多,到目前为止只有一些有趣的线索,但没有任何工作。

我试着添加下面的nginx.conf(这就是为什么我的实际nginx.conf有这些行),但它没有解决我的问题。

 location ~* \.php$ { include fastcgi_params; fastcgi_index index.php; fastcgi_read_timeout 240; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } 

有关信息,这里是日志文件中的错误:

2017/02/10 18:14:07 [错误] 18555#18555:上游超时(110:连接超时),上游读取响应头,客户端:xxx.xxx.xxx.xxx,服务器:示例。 com,请求:“POST /wp-admin/admin-ajax.php HTTP / 1.1”,上游:“fastcgi:// unix:/run/php-fpm/php56-fpm.sock”,主机:“www.example .com“,referrer: http : //example.com/wp-admin/admin.php? page= laborator- demo-content-installer& install- pack= agency&

如果你有任何想法来解决这个问题…因为我几周以来一直在挣扎…非常感谢

tl; dr-你的WordPress太慢了。 跳转到底部,看看如何让NGINX返回适当的504 GATEWAY TIMEOUT状态码。

更长的版本:你有一堆单独的问题一起工作在一个无益的方式。

1.你的上游服务器的WordPress不够快

这需要超过4分钟,这就是为什么您在日志中看到110: Connection timed out的原因。 缓慢解决方案是加快WordPress的速度。 作为一个解决方法,您可以给它更多的时间来处理请求。 为此,请增加fastcgi_read_timeout 240;的数字fastcgi_read_timeout 240; 规则。 请注意,超时时间是以秒为单位的,所以如果您等待10分钟,请将其设置为600

不过,我建议不要增加超时时间。 你应该真的解决性能问题本身。 如此长的请求会阻止NGINX和WordPress中的资源,因此您可以很容易地甚至是自己偶然地进行DDoS。

由于您的上游时间太长,NGINX会以504 GATEWAY TIMEOUT响应。 它不能因为…

2. POST请求不能用静态文件来回答

在你的error_page位置,你告诉NGINX使用静态文件来处理请求。 这对于GETHEAD很好,但是它不适用于POST ,因为它会要求NGINX覆盖/创建文件。 NGINX既不打算也不支持。 (出于同样的原因,使用其他修饰动词(如PUTDELETE也会失败。)

请注意,您正在使用的方法仍然是POST的命名位置@error_page ,如手册所述 :

 If there is no need to change URI and method during internal redirection it is possible to pass error processing into a named location. 

你已经知道这个的一部分,这就是为什么你添加error_page 405 =200 $uri; 规则。 不幸的是,这并没有拯救你,因为…

3.默认情况下,内部error_page重定向不是递归的

就我error_page ,这在error_page手册的文档中没有提及,但在以下指令的文档中提到:

解决方法:启用递归error_page重定向

指令recursive_error_pages允许您处理在处理前一个错误时发生的错误。 从文档:

  Enables or disables doing several redirects using the error_page directive. The number of such redirects is limited. 

如果你启用这个,通过把recursive_error_pages on; 到你的服务器块,你将允许error_page 405指令。

不幸的是,由于您仍在使用您的$uri部分请求相同的资源,所以WordPress将再次针对相同的URL进行查询,这次是使用GET请求。 不知道你的WordPress如何处理,但是可能发生的错误将不会帮助你进行调试。

这真的只是跳过这个问题; 你应该得到的是原始的504 。 因此,我建议你做下面的事情,而不是启用递归错误页面重定向:

解决方案:使用GET获取错误页面

我假设你仍然想要返回你的error.html甚至POST请求。 为此,您需要强制NGINX删除POST并使用GET处理错误,以便可以使用静态文件。 我发现做到这一点的唯一方法是不使用命名的位置(在开始时使用@ ),而是使用内部的位置 。

要使用此选项,请将您的@error_page位置更改为包含伪路径和internal指令,例如:

  location /error_page { internal; root /usr/syno/share/nginx; rewrite (.*) /error.html break; } 

之后,修改error_page指令,以使用新的位置:

  error_page 403 404 500 502 503 504 /error_page; 

资源: 有关NGINX邮件列表的讨论。