天天看点

php-fpm 超时,小心 php fpm 的超时

一次线上问题,让我意识到,fpm 居然是用这种方式处理超时的,虽然有点震惊,但是想想,这才是我大 PHP 处理问题的方式,简单粗暴而且高效。

问题的现象是这样的,某个接口访问量大增,然后接口大量502,接着 fpm 的机器cpu暴涨,最后gg。

fpm 处理超时的方式非常简单,那就是,直接退出 worker 子进程。

对于超时的处理,fpm 的代码里是这样写的的(我隐去了细节,有兴趣的可以去 PHP 官网下载一份源码看看,在源码的 sapi/fpm 目录里) 检测超时

static void fpm_pctl_check_request_timeout(struct timeval *now)

{

……

fpm_request_check_timed_out(child, now, terminate_timeout, slowlog_timeout);

……

}

处理超时

void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now, int terminate_timeout, int slowlog_timeout)

{

……

fpm_pctl_kill(child->pid, FPM_PCTL_TERM);

……

}

}

然后kill

int fpm_pctl_kill(pid_t pid, int how)

{

……

return kill(pid, s);

}

然后问题就清楚了,接口里有个服务超时,造成fpm超时,fpm worker 进程不断被kill掉并拉起新的 fpm worker 进程,然后不断的这样 kill 然后拉起,cpu 就暴涨,最后 gg。

这个问题怎么避免,去掉 fpm 超时是万万不可取的,只能严格控制代码,调用每一个外部服务必须设置超时时间,而且这个超时时间必须小于 fpm 超时时间。

更多架构、PHP、GO相关踩坑实践技巧请关注我的公众号:PHP架构师