Swoole 给自己定位于一个 PHP 的异步、并行、高性能网络通信引擎,其强大的性能背后依赖的是来自多线程的提供的支持。而在 Swoole 学习系列的开篇中我们也将一睹 Swoole 的进程、线程结构背后的风采。
Swoole 的进程模型
Swoole 的的进程分为三层:期中 Master 进程属于主进程,该进程创建后会自动创建 Manager 管理进程和 Reactor 线程等工作进/线程。 其结构如下图所示: 其中: Swoole 的主进程 Master 进程其根本上是一个多线程的程序。 Reactor 线程实际运行 epoll 实例,用于 accept 客户端连接以及接收客户端数据; Manager 进程为管理进程,该进程的作用是创建、管理所有的 Worker 进程和 Task 进程。
Swoole 的进程详解
Manager 进程
manager 进程是 swoole 的管理进程,负责 fork 管理 worker 和 task 进程。 其运行流程如下: 详细流程如下: 其进程、线程管理方式如下: 子进程结束运行时,manager 进程负责处理子进程的回收工作,避免出现僵尸进程,然后再自行创建新的子进程。 服务器关闭时,manager 进程将会发送信号给所有子进程,通知子进程关闭服务。 当执行 reload 操作时时,manager 进程会逐个的关闭并重启所有的子进程。
Worker 进程
Worker 进程是 Swoole 的实际工作进程,所有的业务逻辑均在此进程上执行。当 Reactor 线程接收到来自客户端的数据后,会将数据打包通过管道发送给某个 Worker 进程。
Worker 进程的生命周期
Worker 进程创建后,会自动执行 onWorkerStart 回调,随后进入事件轮询等待接收数据。当通过回调函数接收到数据后,开始处理数据。当 Worker 进程异常退出,如发生 PHP 的致命错误、被其他程序误杀,或达到 max_request 次数之后正常退出。主进程会重新拉起新的 Worker 进程。其处理模式为同步阻塞或者异步非阻塞。
Task 进程
Task 是 Swoole 中一种特殊的工作进程,该进程的作用是处理一些耗时较长的任务,以达到释放 Worker 进程的目的,其处理方式为同步阻塞模式。
Reactor 线程
Reactor 线程是 Swoole 进程内的一组非常重要的线程,是负责的处理 TCP 连接,收发数据的线程。 Reactor 线程处理机制: Swoole 的主线程在 Accept 新的连接后,会将这个连接分配给一个固定的 Reactor 线程,并由这个线程负责监听此 socket。在 socket 可读时读取数据,并进行协议解析,将请求投递到 Worker 进程。在 socket 可写时将数据发送给 TCP 客户端。 需要注意的是:Reactor 线程在处理 TCP 和 UDP 时是有差异的。 在处理 TCP 客户端连接时,Worker 进程处理完请求后,调用 $server->send 会将数据发给 Reactor 线程,由 Reactor 线程再发给客户端。 在处理 UDP 客户端连接时,Worker 进程处理完请求后,调用 $server->sendto 会直接发给客户端,无需经过 Reactor 线程。
附录(各进线程回调事件):
进程 | 回调函数 |
---|---|
Master 进程 | onStart onShutdown onMasterConnect onMasterClose onTimer |
Worker 进程 | onWorkerStart onWorkerStop onConnect onClose onReceive onTimer onFinish |
Task 进程 | onTask onWorkerStart |
Manager 管理进程 | onManagerStart onManagerStop |