php-fpm的reload过程

背景

谈谈PHP的Reload操作中提到reload会让sleep提前结束,所以就探究了下fpm的reload操作如何实现。

本文在php7.0 fpm下分析,process_control_timeout设置不为0。


重启信号

首先,我们从PHP源码可以知道,fpm的reload操作实际上就是对fpm进程发送了USR2信号。

程序在处理信号的时候,主进程的逻辑相当于“暂停”了,如果在这儿执行一些操作的话,第一,有些局部变量拿不到;第二,可能会打断主进程的逻辑。所以,信号处理函数仅仅是通知主进程,用户发送了这个信号。

信号处理函数的注册

fpm的master进程中,fpm_signals_init_main函数通过sigaction注册了信号处理函数sig_handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int fpm_signals_init_main() /* {{{ */
{
struct sigaction act;

// 。。。。。。

memset(&act, 0, sizeof(act));
act.sa_handler = sig_handler;
sigfillset(&act.sa_mask);

if (0 > sigaction(SIGTERM, &act, 0) ||
0 > sigaction(SIGINT, &act, 0) ||
0 > sigaction(SIGUSR1, &act, 0) ||
0 > sigaction(SIGUSR2, &act, 0) ||
0 > sigaction(SIGCHLD, &act, 0) ||
0 > sigaction(SIGQUIT, &act, 0)) {

zlog(ZLOG_SYSERROR, "failed to init signals: sigaction()");
return -1;
}
return 0;
}
/* }}} */
阅读更多