不懂博客—所知甚少因而建立此博客记录不懂知识;学习、关注、体验互联网。

lnmp架构nginx轮询php服务池解决经常502的方法

来源:fcbu.com 作者:不懂 时间:2012-10-25 【 打印

网站架构采用的就是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。

分类目录: 电脑维修 > linux > | 标签:linux nginx php php-fpm
上一篇:让history显示详细执行时间,及linux历史命令使用技巧
下一篇:iptables防火墙recent模块使用方法示例详解

验证码:点击输入框获取验证码

评论列表

vpser 2013-04-03 11:00 回复

不错,转了。

王谢兵 2012-11-27 12:09 回复

不错,用了你的方法试了3天了,一个502都没有,以前是一天出现好多次。
总算不用担心被老板说网站总出问题了。
谢谢博主了。

侦探 2012-11-16 14:13 回复

学习了,按你的方法操作了一下,以前我天天都会遇到的502问题终于解决了。
感谢!
查看全部3条评论