前言
PHP-FPM是PHP程序员必须用到的软件,但是做到真正懂PHP-FPM的人,我感觉不多,其中也包括我自己。
PHP-FPM工作模式
PHP-FPM是Master&Worker模式,Worker是同步阻塞方式处理请求,即同一时刻只处理一个请求。
接着说一下PHP-FPM的多进程模式:static,dynamic,ondemand三种模式。
static:启动固定数量的Worker。
dynamic:根据Worker忙闲情况动态管理数量。
ondemand:按需生产Worker,当请求来了才创建Worker处理。
image.png
和Nginx一样的是Master都是管理Worker,完全不参与业务,Worker一心工作。
和Nginx不同的是,PHP-FPM的worker工作模式不是epoll等待事件,性能当然也就差了几个级别。
在这里我不讨论三种工作模式的差异。
PHP-FPM的Master和Worker通信
这里就涉及到进程间通信。
常见的通信方式有
信号量
管道
共享内存
命名管道
队列消息
在PHP-FPM 中涉及到对Worker忙闲的判断和处理,开始的时候我以为是用信号,但是这里就涉及到进程间通信方式的区别,我下面重点说一下信号量和共享内存
什么是信号量
软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。信号机制除了基本通知功能外,还可以传递附加信息。
我简单理解就是能打断进程运行的机制,类似于人在睡觉的时候被电话叫醒,信号只是简单的数字。所以在对Worker忙闲判断的逻辑中就要使用到共享内存,类似一所房子有客厅是公用的,房间是私人的。
什么是共享内存
享内存就是允许两个或多个进程共享一定的存储区。就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。因为数据不需要在客户机和服务器端之间复制,数据直接写到内存,不用若干次数据拷贝,所以这是最快的一种IPC
image.png
PHP-FPM将判断Worker进程忙闲时使用共享内存,管理(kill或fork)Worker使用信号量。
优化点
由上述看PHP-FPM是同步阻塞式意味着一次请求从处理到完毕所有与请求相关的资源都会被释放。
那意味着
资源不必手动释放
长连接是个辣鸡
请求不结束,这个Worker就等着
所以基于上述特性,我们需要做以下优化
PHP-FPM一定要设置超时时间,一般3-5秒,业务3秒处理不完就是系统辣鸡。
PHP-FPM中尽量少做耗时IO(例如请求http,保存文件等)。
PHP-FPM尽量要开启yac等缓存,加速处理请求。
PHP-FPM选用高性能机器Static模式,多开一些worker(毕竟很多worker其实都是以网络IO等待为主)
接受
谢谢观看,欢迎斧正