lnmp架构nginx轮询php服务池解决经常502的方法
网站架构采用的就是linux nginx php(php-fpm模式) mysql
网站经常会出现502错误,可以从一下几个方面着手查:
检查下php-fpm的进程数使用情况:
netstat -napo |grep "php-cgi" | wc -l
如果这个查询出来的数量超过了php-fpm.conf里设置的数量,说明是进程数量不够用,可以适当增加。
也可能是php程序执行时间过长造成超时,如果是这个问题,可以通过修改nginx.conf和php-fpm.conf里面相关的超时设置来解决
nginx.conf里面主要是如下
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
php-fpm.conf里如要是如下
request_terminate_timeout 设置为0s或者比目前时间更长,0s表示无限制,一直执行下去。
还可能是fastcgi缓存不够,主要是在nginx.conf配置里修改如下参数:
fastcgi_buffer_size 128
fastcgi_buffers 8 128k;
fastcgi_busy_buffers_size 256k
另外还有注意系统各方面的限制ulimit -a查看一下。
一般上面几个地方做合适的优化,会有较明显的效果。
最后的解决方法:nginx轮询php服务池避免502
既然上面的常规办法不能解决,那就得想其他办法了。502引起肯定是因为php-fpm引发的,也就是nginx将正确的客户端请求发给了后端的php-fpm进程,但是因为php-fpm进程的问题导致不能正确解析php代码。最终返回给了客户端502错误。nginx既然upstream可以支持多组后端服务器轮询实现简单的负责均衡,并且可以做简单的健康检查,因为有了健康检查机制,这样就可以在错误到达客户端前换另外一个php-fpm进程重新解析了。那就用这个办法开多组php-fpm服务来实现一个php-fpm池,让nginx在这个php-fpm资源里通过stream轮询。
使用不同端口或php-fpm.sock启动多个php-fpm主进程的方法:
先修改php-fpm.conf来开启多组php-fpm进程
以/usr/local/php/etc/php-fpm.conf为样板,复制另外3个文件出来,假设为php-fpm_fcbucom1.conf,php-fpm_fcbucom2.conf,php-fpm_fcbucom3.conf;原有的php-fpm.conf不动,作为备份吧。
三个配置文件中,需要修改的两个地方是pid文件名和sock文件名,假设为/tmp/php-cgi_fcbucom1.sock , /tmp/php-cgi_fcbucom2.sock , /tmp/php-cgi_fcbucom3.sock (也可以设置不同的pool名字,默认是default)
执行命令使用不同的配置文件启动3个创建sock监听的PHP-FPM主进程。
/usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm_fcbucom1.conf
/usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm_fcbucom2.conf
/usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm_fcbucom3.conf
启动之后,就在相应目录(一般是/tmp/)出现php-cgi_fcbucom1.sock , php-cgi_fcbucom2.sock , php-cgi_fcbucom3.sock这3个sock文件。
接下来修改nginx.conf配置
主要在http {} 的配置块内,加入我们要使用的轮询配置:
upstream FCBUcom_php_servers{
server unix:/tmp/php-cgi_fcbucom1.sock;
server unix:/tmp/php-cgi_fcbucom2.sock;
server unix:/tmp/php-cgi_fcbucom3.sock;
}
fastcgi_next_upstream error timeout invalid_header http_500 http_503;
#注:fastcgi_next_upstream 不需要加http_502,也加不上去的,不支持。
这样我们就建立了一个可以根据健康状况轮询并可以重试的资源池。
接着修改我们网站server配置,原来处理php代码的fastcgi配置
location ~ .*\.(php|php5)?$
{
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
或原来这样
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
将其中的fastcgi_pass由原来的php-cgi.sock.sock单独的php-fpm进程或127.0.0.1:9000修改为刚刚创建的FCBUcom_php_servers轮询池,如:
location ~ .*\.(php|php5)?$
{
fastcgi_pass FCBUcom_php_servers;
fastcgi_index index.php;
include fastcgi.conf;
}
原有配置文件的每段类似这种location ~ .*\.(php|php5)?$ {代码都需要对fastcgi_pass这行修改。
通过这样的配置,可以肯定的是php-fpm因为采用3个资源池来轮询工作,并且有fastcgi_next_upstream进程简单的健康检查,可以最大程度的避免502错误发生了。
最后重启php-cgi和nginx。