一、背景
此问题产生原因比较复杂,主要讲述一下,从几个点入手吧。
二、解决方案:
1.配置 proxy:
502错误最通常的出现情况就是后端主机当机。在upstream配置里有这么一项配置:proxy_next_upstream,这个配置指定了nginx在从一个后端主机取数据遇到何种错误时会转到下一个后端主机,里头写上的就是会出现502的所有情况拉,默认是error timeout。error就是当机、断线之类的,timeout就是读取堵塞超时,比较容易理解。
2.查看 FastCGI 进程数 :
ps -fe |grep "php" | grep -v "grep" | wc -l //查看开了多少 fastCGI 进程数
netstat -anop | grep "php" | grep -v "grep" | wc -l //查看已有多少 fastCGI 处理 TCP 请求
如果这两个数字 接近 配置项;则说明 配置的 进程数 太少,可适当增加配置进程数。
3.FastCGI 执行时间过长:
适当增加 fastcgi 执行时间
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
4.缓冲区不足:
打开 nginx 错误日志: pstream sent too big header while reading response header from upstream
fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;
client head buffer
5.响应时间超时:
查看 php-fpm 配置文件中:request_terminate_time
max_execution_time 最大执行时间,0为无限制
6.max_children 和 max_requests 联合调优:
查看 php-fpm 日志:fpm_unix_init_main(), line 271: getrlimit(nofile): max:51200, cur:51200
max_requests 指明 每一个 children 处理多少请求后便会关闭,默认为 500。php 把请求轮询分发给每一个children,在大流量下,每一个children 达到 max_requests 的时间几乎相同,造成 children 在同一时间关闭。nginx无法将 php 请求交给 php-fpm 处理,因此 CPU 会降低(不处理 PHP,不执行 SQL ),网卡流量也会降低(nginx无响应数据返回给客户端),而负载会升高(children的开启、关闭,nginx 等待 php-fpm )。
7.阿里云SLB服务
检查 阿里云SLB配置是否禁用 http put/delete
8.查看内存、磁盘IO、mysql IO 使用情况
主要是 php_ini 中 memory_limit 设置,如果偏低的话,适当成倍的调高 配置项即可
同一时间频繁读写一份文件也会造成此问题出现,适当延长缓存时间或者修改缓存策略
mysql 大量的读写,产生阻塞,也会产生超时响应,查询缓存、读写分离
9.代码问题
如果代码中含有无法调用的函数,也会报500错误,主要查看 php-fpm 的日志
综上:服务器 500 错误是由多方引起的系统问题,此问题比较恶心,需要运维和开发一起协同完成
参考资料:
1.http://www.jianshu.com/p/d028a37890b7
2.https://yq.aliyun.com/articles/84922
3.https://yq.aliyun.com/ask/1118