问题描述
浏览器访问 URL 地址,页面显示 502 Bad Gateway 信息。
问题原因
导致该问题可能有多种原因:
第一种、服务未启动
没有启动 PHP-FPM 服务导致 Nginx 无法访问,因此返回 502 错误。
第二种、配置错误
虽然启动 PHP-FPM 服务,但是 Nginx 配置错误。
比如 Nigix 连接 9000 端口,但是 PHP-FPM 监听 sock 文件。
第三种、进程提前退出
这些问题都是因为 PHP-FPM 工作进程退出,导致连接关闭。
在 Nginx 中将看见 104: Connection reset by peer 消息:
2020/05/28 16:30:58 [error] 915#0: *17358 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 192.168.50.1, server: www.example.com, request: "HEAD /path/to /somewhere HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.example.com"
但是 PHP-FPM 的错误日志可能不同:
#1 child <PID> exited on signal 11 (SIGSEGV)
在 PHP-FPM 中,错误日志(对应时间点):
[28-May-2020 16:30:58] WARNING: [pool www] child 3359 exited on signal 11 (SIGSEGV) after 7066.544041 seconds from start [28-May-2020 16:30:58] NOTICE: [pool www] child 21771 started
至于问题原因嘛,也是各种各样(php-fpm child process exited on signal 11)
对于我们的场景,也没啥高级的排查思路:
1)从日志看,SIGSEGV,这是段错误的信号,那就是说 PHP-FPM 程序异常退出
2)那就看内核日志信息,dmesg | grep -F "php-fpm[<PID>]",在输出中显示 memcache.so 程序段错误
3)那我们能猜测的大概原因是:在程序中,使用的 Memcache 插件存在 BUG 导致段错误。
TODO ! 通过 dmesg 排查进程错误。
#2 fastcgi_read_timeout > request_terminate_timeouts
在 Nginx 中,默认 CGI 超时由 fastcgi_read_timeout 指定,默认为 60 秒。
在 PHP-FPM 中,参数 request_terminate_timeout 指定工作进程处理单个请求的超时时间。
如果 fastcgi_read_timeout > request_terminate_timeout 参数,PHP-FPM 进程提前退出,Nginx 返回 502 Bad Gateway 错误。
如果 fastcgi_read_timeout < request_terminate_timeout 参数,Nginx 等待超时,返回 504 Gateway Timeout 错误。
参考文献
NGINX 502 Bad Gateway: PHP-FPM
PHP/List of global php-fpm.conf directives
nginx errors readv() and recv() failed
PHP-FPM and continuos “exited on signal 11”
What causes a SIGSEGV