一、背景

早上突然发现服务器这边所有的请求都报错:502,具体报错信息如下:

connect() to unix:/var/run/php5-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: xxx, server: xxx, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "xxx"

这个意思是无法找到php5-fpm.sock,但是原来是好好的,为什么会出现这种问题呢?

二、第一种可能

1、第一种可能就是,nginx配置的问题:

nginx配置文件中有一句是这样的,监听sock文件
fastcgi_pass unix:/var/run/php5-fpm.sock;

2、解决方案

进入 /etc/php5/fpm/pool.d/www.conf,修改配置,里面找到这样一段代码:

```
listen = 127.0.0.1:9000 
```

在这上面代码的下面添加一行:

```
listen = /var/run/php5-fpm.sock
```

保存后启动php5-fpm

```
/etc/init.d/php5-fpm restart
```

这时就可以正常访问了

三、第二种可能

1、既然是报错502,众所周知,这个错误代表的意思就是:

       这个错误是由于服务器压力过大,不能及时处理client的请求导致服务器响应超时而抛出的错误。通俗来讲,我们向服务器发送请求 由于服务器当前链接太多,导致服务器方面无法给于正常的响应,产生此类报错。

       那么OK,因为我们使用的是php-fpm的系统服务,那么极有可能是我们在给服务器请求的时候,由于请求量比较大,php-fpm在规定的响应时间内没有响应,自动杀掉这些进程或者卡死造成的。

2、解决方案

1)增大请求的持续时间,防止php脚本或者php-fpm自动杀死进程

//修改php.ini 中的参数,可以把这个参数设置的大一些,
代表置了脚本被解析器中止之前允许的最大执行时间
,默认是30s。也就是说这个请求如果30s还没得到响应的话
,脚本会自动杀死这个请求。
max_execution_time = 60s

       如果不想修改php.ini文件的话,可以选择修改php-fpm.conf文件,因为在服务器正常运行的时候,php-fpm.conf中的request_terminate_timeout 会覆盖php.ini中的max_execution_time

request_terminate_timeout = 60s
#表示等待60秒后,结束那些没有自动结束的php脚本,以释放占用的资源。
当PHP运行在php-fpm模式下,php.ini配置的max_execute_time是无效的,需要在php-fpm.conf中配置另外一个配置项:request_terminate_timeout;

       如果你的服务器性能足够好,且宽带资源足够充足,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这个错误。

PS:这个部分,我的php-fpm.conf中并没有这个参数,因此我是自己加上去的。

2)修改php-fpm给子进程分配的时间间隔

这里修改的是php-fpm.conf中的 process_control_timeout 参数

解释:php-fpm和FastCGI的关系:

       关于process_control_timeout项配置的由来及详细介绍,依靠CGI接口,Nginx把收到的请求转给PHP,并从PHP获得返回数据,但CGI实现逻辑是一次请求建立一个PHP进程,处理结束的同时关闭php进程,而php进程的每次启动销毁都很耗资源,于是出现了FastCGI的方式,一个fastcgi进程可以处理多个请求再关闭,但FastCGI依然有缺点,因为fastcgi是单个进程串行,即同一时刻只能处理一个请求,于是php-fpm就出现了,它的作用就是可以管理多个fastcgi。从而实现同时处理多个请求。php-fpm就和nginx的主进程一样,而每一个处理请求的php进程就像是nginx里的多个执行线程。这就是php进程的复用。php-fpm作为一个调度员,会自动让空闲的FastCGI进程去处理请求,但是在分配请求给php进程前,PHP-FPM需要发送一个进程复用信号给FastCGI,以让FastCGI准备请求处理。但是FastCGI进程并不总是能够处理请求,也就是不能够响应进程复用信号,这个参数就表示了PHP-FPM留给FastCGI进程多久时间去响应进程复用信号,如果超时PHP-FPM会选择其他的fastcgi去处理。这段也是从网上找到的,以我的理解进行了一些修改。从英文注释来看,这个配置是子进程等待主进程的超时时间。可能和上面的描述有细微的出入,但也不妨对功能进行理解。

process_control_timeout = 20

       通过以上的描述,我们就知道了,设置这个参数相当于给程序更多的响应时间,以免出现502的情况。

3) 修改php-fpm自动重启的时间

这里需要修改的参数还是php-fpm.conf中的参数:

#表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果
#超过emergency_restart_threshold个php-fpm就会优雅重启。这两个选项一般保持默认值

emergency_restart_threshold = 60
emergency_restart_interval = 30s

       这两个参数的意思就是在30秒内出现SIGSEGV或者SIGBUS错误的php-cgi进程数超过60个,则会自动重启php-fpm。

这里的emergency_restart_threshold是需要根据自己的服务器性能来计算的,计算方式为:

比如一个fastcgi进程占用的内存为30M,则1G的服务器,最大能设置的值为  1024/30 = 34
但实际上我们不可能把所有的内存都用来出来这些东西,所以设置成30是比较合适的。

end

参考链接:
php-fpm.conf重要参数详解

php-fpm超时时间设置request_terminate_timeout分析

php-fpm参数调优

更多推荐

nginx报错502:connect() to unix:/var/run/php5-fpm.sock failed (2: No such file or d