我们在 RHEL 6.6 上的 Web 服务器 Varnish + Nginx + FastCGI (php-fpm) 上运行以下堆栈
它是一个动态网站,每次都有不同的结果集,并且有大约 200 万个 URL 被 Google 索引。
- 它在 nginx/1.5.12 和 PHP 5.3.3 上运行(即将升级到最新的 nginx 和 PHP)
- Nginx 连接到在端口 9000 上同一台服务器上本地运行的 php-fpm
我们在一些我们无法解决的页面上间歇性地收到 504 网关超时。一段时间后,给出 504 的 URL 可以正常工作。我们从日志中了解了 504,但我们无法复制它,因为它随机发生在任何 URL 上并且在一段时间后会起作用。
我已经与开发人员进行了几次讨论,但根据他的说法,底层的 php 脚本几乎没有任何作用,它不应该花费这么长时间(120 秒),但它仍然给出 504 网关超时。
需要确定问题发生的确切位置:
- 是 Nginx 的问题吗?
- php-fpm 有问题吗?
- 底层php脚本有问题吗?
- nginx 是否有可能无法连接到 php-fpm ?
- 如果我们使用 Unix 套接字而不是 TCP/IP 连接,它会解决吗?
URL 在 120 秒后超时,出现 504
以下是看到的错误: 2016/01/04 17:29:20 [error] 1070#0: *196333149 upstream timed out (110: Connection timed out) while connection to upstream, client: 66.249.74.95, server: xxxx,请求:“GET /Some/url HTTP/1.1”,上游:“fastcgi://127.0.0.1:9000”,主机:“example.com”
较早的 fastcgi_connect_timeout 为 150 秒 - 在 RHEL 6.6 上默认 net.ipv4.tcp_syn_retries = 5 时,它在 63 秒后给出 502 状态码;之后我们设置 net.ipv4.tcp_syn_retries = 6 然后它在 127 秒后开始给出 502。
一旦我设置了 fastcgi_connect_timeout = 120 它就开始给出 504 状态码。我了解如此高的值的 fastcgi_connect_timeout 并不好。
需要找出为什么我们会得到 504(我知道它的超时,但原因未知)。需要找到根本原因才能永久修复它。
我如何确认问题到底出在哪里?
以下是一些已经定义的超时:
在服务器范围的 nginx.conf 下:
- keepalive_timeout 5;
- 发送超时 150;
在特定的 vhost.conf 下:
- proxy_send_timeout 100
- proxy_read_timeout 100
- proxy_connect_timeout 100
- fastcgi_connect_timeout 120
- fastcgi_send_timeout 300
- fastcgi_read_timeout 300
使用了不同的超时值,因此我可以找出确切触发了哪个超时。
以下是 sysctl.conf 中的一些设置:
- net.ipv4.ip_local_port_range = 1024 65500
- net.ipv4.tcp_fin_timeout = 10
- net.ipv4.tcp_tw_reuse = 1
- net.ipv4.tcp_syn_retries = 6
- net.core.netdev_max_backlog = 8192
- net.ipv4.tcp_max_tw_buckets = 2000000
- net.core.somaxconn = 4096
- net.ipv4.tcp_no_metrics_save = 1
- vm.max_map_count = 256000
如果它的代码写得不好,那么我需要通知开发人员 504 是由于 php 代码中的问题而不是由于 nginx 或 php-fpm 而发生的,如果它是由于 Nginx 或 Php-fpm 导致的,那么需要修复它。
提前致谢!
======
进一步更新:
有2种情况:
- 504 @ 120 秒出现以下错误:
2016/01/05 03:50:54 [错误] 1070#0: *201650845 连接到上游时上游超时(110:连接超时),客户端:66.249.74.99,服务器:xxxx,请求:“GET /some /url HTTP/1.1”,上游:“fastcgi://127.0.0.1:9000”,主机:“example.com”
- 504 @ 300 秒出现以下错误:
2016/01/05 00:51:43 [错误] 1067#0: *200656359 从上游读取响应标头时上游超时(110:连接超时),客户端:115.112.161.9,服务器:192.168.12.101,请求: “GET /some/url HTTP/1.1”,上游:“fastcgi://127.0.0.1:9000”,主机:“example.com”
- 在 php-fpm 日志中未发现错误。
php-fpm 进程数也正常。后端看起来并没有超载,因为其他请求同时得到了很好的服务。
只使用了一个 php-fpm 池。一个 php-fpm 主(父)进程和其他从(子)进程通常只有在观察到 5xx 时才处于正常范围。php-fpm 进程的数量没有显着增长,即使增长,服务器也有足够的容量来分叉新进程并服务请求。