php-fpm
php-fpm master进程负责创建和管理woker进程,同时负责监听listen连接,master进程是多路复用的;woker进程负责accept请求连接,同时处理请求,一个woker进程可以处理多个请求(复用,不需要每次都fork一个woker进程),但一个woker进程一次只能处理一个请求(请区别理解和前一句话的意思)。以下伪代码说明一下关系:
好处是,复用worker进程,woker进程可以处理多个请求,试想一下,我们使用mysql、redis长连接的时候,连接状态是保存在woker进程的,这样后面的请求就可以直接使用,不需要每次都经历TCP握手。
验证
为了证实,一个woker进程一次只处理一个请求,可以把php-fpm配置的pm.max_children改成1,即只有一个woker进程处理请求,在这种请求下实现一个计数器,每个请求都加1,数据保存在文件中,读写文件不上文件锁,使用ab进行压测,查看最后结果加上失败次数是否和压测总请求量相等。
结语
php-fpm.conf有个配置项events.mechanism = epoll,指定事件驱动模型,但是这个是配置指定master进程的,不是woker进程的,以上例子可以看出,woker进程是单进程单线程模型。复用woker进程,处理多个请求好处是挺多的,每个woker进程启动和销毁,都需要执行一遍php扩展的模块初始化、销毁的工作,这部分开销还是挺大的。还有就是mysql、redis长连接等,因为php没有连接池,每次都执行短连接,TCP三次握手耗时,频繁关闭连接还会造成大量TIME_WAIT,造成服务器端口等资源大量消耗。