1.502 Bad Gateway 网关错误
Bab Gateway 502 网关错误,php来说造成502的原因常见的就是脚本执行超过timeout设置时间,或者timeout设置过大,导致php进程长时间不能释放,没有空闲worker进程来执行请求。
1.1 第一种情况【fpm超时】:
php-fpm的worker进程 执行php程序脚本时,超过了配置的最长执行时间,master进程将worker进程杀掉,直接返回502.
返回502后nginx对应error日志是104:Connection reset by peer
控制php执行时间的选项有两个,在php.ini中max_execution_time和php-fpm中request_terminate_timeout。其中request_terminate_timeout可以覆盖max_execution_time,所以如果不想修改全局的php.ini。只能修改php-fpm的配置就可以了。
502 demo:
php-fpm配置:
request_terminate_timeout = 10
php.ini配置:
max_execution_time = 30
编辑test.php
<?php
sleep(40);
echo 111;
?>
浏览器请求:192.168.1.10/test.php
浏览器返回:502
Request URL: http://192.168.1.10/test.php
Request Method: GET
Status Code: 502 Bad Gateway
Remote Address: 192.168.1.10:80
Referrer Policy: no-referrer-when-downgrade
nginx的error.log
[root@192 ~]# cd /usr/local/openresty/nginx/logs/
[root@192 logs]# ls
access.log error.log nginx.pid
[root@192 logs]# cat error.log2020/04/06 11:48:35 [error] 4198#4198: *1 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 192.168.1.2, server: localhost, request: “GET /test.php HTTP/1.1”, upstream: “fastcgi://127.0.0.1:9000”, host: “192.168.1.10”
php-fpm错误日志:
[root@192 log]# cd /usr/local/php7.2/var/log/
[root@192 log]# cat php-fpm.log
[06-Apr-2020 11:48:35] WARNING: [pool www] child 4206, script ‘/usr/local/openresty/nginx/html/test.php’ (request: “GET /test.php”) execution timed out (13.127069 sec), terminating
[06-Apr-2020 11:48:35] WARNING: [pool www] child 4206 exited on signal 15 (SIGTERM) after 16.673493 seconds from start
[06-Apr-2020 11:48:35] NOTICE: [pool www] child 4221 started
说明:child 4206 exited on signal 15 (SIGTERM) after 16.673493 seconds from start此处worker进程长时间占用进程,所以master发送信号kill worker进程
1.2 连接已满:
连接请求数(accept之前)超出了端口所能监听的tcp最大值(backlog值),进不了fpm的部分带accept的链接队列,直接返回502,;返回502后nginx对应的error日志是Connection refused backlog 的值是半连接或全连接的总和,它的存在也有短时间缓冲解耦nginx请求与fpm处理的作用,“半连接”指收到了syn请求,3次握手尚未连接,“全连接”指的是3次握手成功,不过尚未被accept的请求,fpm里面有调节的参数,如果fpm的参数设置为-1,则默认走的是系统内存参数net.core.somaxconn设置的值,如果不设置可以在 /proc/sys/net/core/somaxconn 里查看,默认值是 128,所以在连接请求较高的业务里面要增大这个值。
502优化建议
502主要从php-fpm的配置方面考虑,根据服务器情况,适量增大php-fpm的工作进程数,适当增加php的执行时间,适当增加backlog值。
php的工作进程数也不是越大越好,这种进程模型运行时间长了占用的内存会增大,一般一个php进程占到30M左右的内存。开多少合适具体看机器和服务决定。
nginx的worker进程一般也能跑到30M的内存,综合计算一下:php的执行时间可以根据你的服务标准来设定,超过服务时间浏览器你去返回的502错误,这个按照实际的情况处理,至于backlog值,建议设置器数量为php的工作进程的1到2倍。
php-fpm的进程公式:
- 适用于 dynamic 方式:在 N + 20% 和 M / m 之间。
N 是 CPU 内核数量。
M 是 PHP 能利用的内存数量。
m 是每个 PHP 进程平均使用的内存数量。 - 适用于static方式:M / (m * 1.2)
2.504 Gateway Time-out 网关超时
1.1 第一种情况【nginx连接超时】:
php的worker 进程池处理慢,无法尽快处理等待accept的链接队列,导3次握手后的链接队列长时间没有被accept,nginx链接等待超时;返回504后nginx对应的error日志是110:Connection timed out
1.2第二种情况【nginx超时】:
后端php-fpm执行脚本的时间太长,超过了nginx配置的超时机制,这个时候也是会报504错误的,
nginx超时时间为90秒(keepalive_timeout 90; [nginx.conf])
php-fpm的超时时间300秒 (request_terminate_timeout = 300】[php-fpm.d/www.conf])
demo: 504 Gateway Timeout
浏览器请求:192.168.1.10/test.php
浏览器返回:504
Request URL: http://192.168.1.10/test.php
Request Method: GET
Status Code: 504 Gateway Time-out
Remote Address: 192.168.1.10:80
Referrer Policy: no-referrer-when-downgrade
nginx的error.log
2020/04/06 21:54:31 [error] 2014#2014: *4 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.1.2, server: localhost, request: “GET /test.php HTTP/1.1”, upstream: “fastcgi://127.0.0.1:9000”, host: “192.168.1.10”
504优化建议
504主要从nginx的配置方考虑,根据业务情况配置好超时的各种机制。在配置过程中,比如遇到大并发或者是特殊业务场景,不合理的fd,buffer等设置也会带来5XX错误,比如说大并发连接的业务要增大系统和单个程序的fd数量,如果是上传业务员要增大buffer等,这些要视情况优化
pm = static | dynamic | ondemand 静态池、服务优先、内存优先 pm.max_children = 256 开启的最大 php 进程数 pm.max_requests = 1024 在执行了 1024 个请 求后重启 worker 进程,避免内存意外增长
web 服务的机器是 12 核 cpu 、 16G 内存, nginx 开启 12 个 worker 进程, php 开启 256 个进程, 跑起来后每个进程大概占用 30M 内存,也就是( 256+12 )* 30=8G, 这种静态池的配置大大减少了prefork 进程带来的开销.