在这边文章中我们将介绍以下内容:
1、Swoole Server 的运行模式
2、Swoole 进程模型分析
上图是 Swoole 官网提供的各个进程相互关系图,可以说理解了这张图,你就理解了 Swoole 的进程模型。
1、Swoole Server 的运行模式
Swoole 服务常见的运行模式有单线程模式和进程模式两种,两种方式介绍如下:
单线程模式 (SWOOLE_BASE) 这种模式就是传统的异步非阻塞 Server,与 Nginx 和 Node.js 等异步服务的原理是一样的。在这种模式下,事件循环会直接回调 PHP 的函数,而不是通过线程 dispatch 投递任务。如果在回调函数中有阻塞操作,就会导致 Server 退化为同步模式。就像在上一篇文章中 Nginx+PHP-FPM 架构中介绍的那样,Nginx 只做转发,具体业务由 PHP-FPM 来实现。假如 Nginx 也可以处理业务逻辑,一旦出现阻塞的业务逻辑,Nginx 的性能会急剧下降。正是因为 Nginx 和 PHP-FPM 所起到的作用不同,才会造就 Nginx 的高性能。Base 模式的特点:没有 Master 进程的角色;每个 Worker 进程同时承担了 Process 模式下 Reactor 线程和 Worker 进程两部分职责;在这种模式下,Manage 进程是可选的,当设置了 worker_num=1,并且么有使用 Task 和 MaxRequest 特性时,底层将直接创建一个单独的 Worker 进程,不创建 Manager 进程 Base 模式的优点:没有 IPC 开销,性能更好;代码简单,不容易出错。Base 模式的缺点:TCP 连接时在 Worker 进程中维持的,所以当某个 Worker 进程挂掉时,此 Worker 内的所有连接都将被关闭;少量 TCP 长连接无法利用到所有的 Worker 进程;TCP 连接与 Worker 进程是绑定的,在长连接应用中,不同的 Worker 进程无法实现负载均衡。例如:某些连接的数据量很大,这些连接所在的 Worker 进程的负载会非常高。但是某些连接数据量很小,所在 Worker 进程的负载会非常低。Base 模式适用场景:如果客户端连接之间不需要交互,可以使用 Base 模式。如 Memcache、Http 服务等。
进程模式 (SWOOLE_PROCESS) 多进程模式比较底层实现比较复杂,用了大量进程间通信、进程管理机制。适合业务逻辑非常复杂的场景。Swoole 提供了完善的进程管理、内存保护机制。在业务逻辑非常复杂的情况下,也可以长期稳定运行。
2、Swoole 进程模型
从上图中可以看出,Swoole 在启动后会创建 Master 进程和 Manager 进程。Master 进程会创建 Master 线程、Reactor 线程、心跳检测线程等,Manager 进程会创建 Worker 进程和 Task 进程。
Swoole 的线程和进程之间分别有什么作用呢?
Master 进程这个进程是 swoole 的核心进程,也是一个多线程的进程,一个 Master 线程和多个 Reactor 进程,Reactor 线程的数量可以配置。
Master 线程 Master 线程用于 accept 新的连接,然后会评估每个 Reactor 线程维护的连接数,最后将这个新的连接分配给连接数量最少的那个 Reactor 线程,从而保证每个 Reactor 线程的负载量是均衡的。Master 线程还负责对所有信号的接管(包括请求处理、重启进程、重载配置等),避免 Reactor 线程收到信号的打扰中断。
Reactor 线程当一个 socket 可读或可写的时候,就由 Reactor 线程将事件转发给 worker 进程。
Manager 进程 Manager 进程管理着 Worker 进程和 Task 进程,Worker 进程和 Task 进程是由 Manager 进程 fork 出来的。Manager 进程会监管 Worker 进程和 Task 进程的状态,当他们意外挂掉时,Manager 进程会重新拉起新的进程,Manager 进程还负责 Worker 进程和 Task 进程的平滑重启。
Worker 进程 Worker 进程是由 Manager 进程 fork 而来,用于处理具体的业务逻辑。Worker 进程可以用同步的方式去干活,也可以用异步的方式去干活。
Task 进程 Task 进程是一种特殊的 Worker 进程,专门用于处理一些比较耗时的操作。Task 进程只能工作在同步的方式下,不能使用异步。所以 Task 进程中不能使用定时器,而 Worker 进程可以。
以上就是本文的全部内容,如有错误,请指正!可以相互关注,方便一起交流技术心得。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。