妖怪幻 发表于 2016-12-27 09:26:46

nginx的50X错误与php-fpm配置的优化

  情况:高并发下,请求a所在的php-fpm进程顺利访问到资源,但是还没有执行完毕,请求b一直没能获得可用的php-fpm进程,此时请求b就会被返回504的错误,
  如果此时过多的504和其他问题导致整个fpm、nginx出现问题,那么还没有执行完毕的php-fpm进程所在的请求a就会出现502错误(因为进程被终止了)
  Nginx 502 Bad Gateway的含义是请求的PHP-CGI(这里使用的是php-fpm)已经执行,但是由于某种原因(一般是读取资源的问题)没有执行完毕而导致PHP-CGI进程终止(执行中php-fpm进程挂掉了的意思)。
  一般Nginx 502 Bad Gateway和php-fpm.conf和php-fpm.conf的设置有关,例如:
  1.FastCGI进程是否已经启动
  2.FastCGI worker进程数是否不够
  3.FastCGI执行时间过长
    fastcgi_connect_timeout 300; #连接时间
    fastcgi_send_timeout 300;    #发送时间 
    fastcgi_read_timeout 300;    #读取时间
  4.FastCGI Buffer不够
    fastcgi_buffer_size 32k;
    fastcgi_buffers 8 32k;
  5.Proxy Buffer不够(如果你用了Proxying)
  6.https转发配置错误
  7.php脚本执行时间过长(request_terminate_timeout选项值)
  Nginx 504 Gateway Time-out的含义是所请求的网关没有请求到,简单来说就是没有请求到可以执行的PHP-CGI(等很久了还是没有可用的php-cgi进程了的意思)。
  一般Nginx 504 Gateway Time-out则是与nginx.conf和php-fpm.conf的设置有关
  1.FastCGI执行时间过长:(该选项也会导致502错误,选项是在nginx.conf的http、server、location域中设置,单位为秒)
    fastcgi_connect_timeout 300; #连接时间
    fastcgi_send_timeout 300;    #发送时间 
    fastcgi_read_timeout 300;    #读取时间
  Nginx 413错误的排查:修改上传文件大小限制
  在上传时nginx返回了413错误,查看log文件,显示的错误信息是:”413 Request Entity Too Large”, 于是在网上找了下“nginx 413错误”发现需要做以下设置:
  在nginx.conf增加 client_max_body_size的相关设置, 这个值默认是1m,可以增加到8m以增加提高文件大小限制;
  如果运行的是php,那么还要检查php.ini,这个大小client_max_body_size要和php.ini中的如下值的最大值一致或者稍大,这样就不会因为提交数据大小不一致出现的错误。
  post_max_size = 8M
  upload_max_filesize = 2M
  Nginx 400错误排查:HTTP头/Cookie过大
  今天有人汇报nginx的HTTP400错误,而且这个HTTP400错误并不是每次都会出现的,查了一下发现nginx400错误是由于request header过大,通常是由于cookie中写入了较长的字符串所引起的。
  解决方法是不要在cookie里记录过多数据,如果实在需要的话可以考虑调整在nginx.conf中的client_header_buffer_size(默认1k)
  若cookie太大,可能还需要调整large_client_header_buffers(默认4k),该参数说明如下:
  请求行如果超过buffer,就会报HTTP 414错误(URI Too Long)
  nginx接受最长的HTTP头部大小必须比其中一个buffer大,否则就会报400的HTTP错误(Bad Request)。
  php-fpm的一些可优化的配置项:
  pm = dynamic         #对于专用(线上)服务器,pm可以设置为static。#如何控制子进程,选项有static和dynamic。如果选择static,则由pm.max_children指定固定的子进程数。如果选择dynamic,则由下开参数决定:
  pm.max_children      #子进程最大数
  pm.start_servers     #启动时的进程数
  pm.min_spare_servers #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
  pm.max_spare_servers #保证空闲进程数最大值,如果空闲进程大于此值,此进行清理
  ps:其中max_children的值,原则上是越大越好,php-cgi的进程多了就会处理的很快,排队的请求就会很少。设置”max_children”也需要根据服务器的性能进行设定,一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M左右,因此我的”max_children”我设置成40个,20M*40=800M也就是说在峰值的时候所有PHP-CGI所耗内存在800M以内,低于我的有效内存1Gb。而如果我的”max_children”设置的较小,比如5-10个,那么php-cgi就会“很累”,处理速度也很慢,等待的时间也较长。如果长时间没有得到处理的请求就会出现504 Gateway Time-out这个错误,而正在处理的很累的那几个php-cgi如果遇到了问题就会出现502 Bad gateway这个错误。
  pm.max_requests = 1000
  #设置每个子进程重生之前服务的请求数。对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.
  ps:一般在项目中,我们多多少少都会用到一些 PHP 的第三方库,这些第三方库经常存在内存泄漏问题,如果不定期重启 PHP-CGI 进程,势必造成内存使用量不断增长。因此 PHP-FPM 作为 PHP-CGI 的管理器,提供了这么一项监控功能,对请求达到指定次数的 PHP-CGI 进程进行重启,保证内存使用量不增长。正是因为这个机制,在高并发的站点中,经常导致 502 错误(因为同一个进程达到了重启的访问值后,会被强制重启,而正在使用该进程的访问们就会由于该进程的被终止而返回502错误)
  request_terminate_timeout = 0 #设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用. 设置为 '0' 表示 'Off'.当经常出现502错误时可以尝试更改此选项。
  ps:如果你的服务器性能足够好,且宽带资源足够充足,PHP脚本没有系循环或BUG的话你可以直接将”request_terminate_timeout”设置成0s。0s的含义是让PHP-CGI一直执行下去而没有时间限制。而如果你做不到这一点,也就是说你的PHP-CGI可能出现某个BUG,或者你的宽带不够充足或者其他的原因导致你的PHP-CGI能够假死那么就建议你给”request_terminate_timeout”赋一个值,这个值可以根据你服务器的性能进行设定。一般来说性能越好你可以设置越高,20分钟-30分钟都可以。由于我的服务器PHP脚本需要长时间运行,有的可能会超过10分钟因此我设置了900秒,这样不会导致PHP-CGI死掉而出现502 Bad gateway这个错误。
页: [1]
查看完整版本: nginx的50X错误与php-fpm配置的优化