5. swoole 的进程模型
很多 phper 一直停留在 php web 开发的 mvc CURD 中,也听到很多人对自己陷入这种困境中多有不满,但又不知道如何提高自己,摆脱困境。活脱脱就像一直趴在玻璃上的苍蝇,前途一片光明,就是飞不出去,可悲可叹。
话说回来,实际上做到一名合格的 CURDer 也并不是一件容易的事情,万万不可眼高手低。
如果想提高自己,也不一定非要通过工作,我认为一个人的提高更多是在非工作环境中。php 的开发人员开始通过尝试接触并使用 swoole 或者 workerman(0_0 或者等我的 php socket 框架,啦啦啦 0_0)来提高自己的认知水准,这就像2017年那部挺火的电视剧中那样,鼓励大家学英语,我认为挺好的。
学习 swoole 前,我建议大家有最好有如下知识储备或者有准备学习如下知识的准备:
- 多进程多线程知识储备,多进程进程间通信,多进程多线程锁相关,进程管理等
- 服务器 IO 模型相关知识储备
- 熟练的 *NIX 系统操作以及良好的使用习惯
- TCP 协议以及 socket 相关知识储备
考虑到本 PO 主原来叨叨了一坨与进程相关的知识,所以这篇就来一坨与 swoole 进程相关的内容,这也是要学习并好好利用 swoole 的第一课,打好基础,会对你使用有着更大的帮助。
先贴一张图,是从官方 wiki 上偷过来的,不得不说,如果你去 swoole 官方 wiki 上找,都不一定能找到这个图,我的言下之意就是老韩写的文档组织方式以及内容确实比较混乱,没有对比就没有伤害,比如人家 workerman 的文档的,我贴出来,你们感受一下:
swoole 中进程角色
结合上图开始简单描述一下 swoole 中进程角色们:
master 进程
这个进程比较复杂,也是我认为最核心的进程,这是一个包含多线程的进程,分别是一个主线程和 n 个 reactor 线程(数量可以配置)。其中,主线程用于 accept 新的连接,然后评估一下每个 reactor 线程负责维护的连接数,然后分配给数量最少的那个 reactor 线程,最大程度保证每个 reactor 线程的负载量是均衡的。
本质上讲,一旦一个 socket 可读或者可写了,就由 reactor 线程发送给 worker 进程或者发送会客户端。除此之外,主线程还负责对所有信号的接管,避免 reactor 线程收到信号的打扰中断。说的洋气点儿就是:master 进程负责了连接的 accept、托管、socket 的可读可写(数据的发送和接受),本质上讲,master 进程负责了 IO。还需要注意一点儿的是 reactor 线程是彻底的全异步非阻塞工作方式。
manager 进程
manager 进程是 worker 进程和 taskworker 进程的妈,说的洋气点儿就是 manager 进程 fork 出来了 worker 进程和 taskworker 进程,生出来了就得管,所以,manager 进程得负责对worker进程和taskworker 进程的抚养义务,具体包括监控它们的状态、当它们意外挂了后重新拉起一个新的进程(避免了僵尸进程)、平滑重启(就是传说中的 reload)。
worker 进程
worker 进程是 manager 进程 fork 出来的,这个进程说白了就是搬砖干活(官方文档中屡次提到的业务代码),其实就是平时码的那些curd业务逻辑代码,懂了吧?只不过worker进程比较diao的是,这个进程可以用异步方式去工作,也可以用同步方式去工作。如果听不懂什么意思,那就先背过,先混个脸熟再说。
taskworker 进程
taskworker 进程(后文中称 tasker 进程)实际本质上也是 worker 进程,只不过是一种特殊的worker进程。如果你的worker进程中存在一些耗时耗力的操作,那么可以先抛给tasker进程,自己先去干别的,等tasker干完了,再由 worker 进程取回,非常 diao。但是tasker进程只能工作在同步方式下,并不能使用异步。这就是为什么tasker进程不可以使用定时器,而worker进程可以使用定时器的原因。
简单总结
混在一起说下这几种进程之间是怎么搭配起来干活的。见说来说,就是master进程就是接活儿的销售,但是具体干活则由worker进程来做,如果worker进程感觉到某些流程太繁忙复杂就可以让 tasker 进程来做。而manager进程就是后勤 worker 进程和 takser 进程的人力资源保障部,负责他们的生死存亡和吃喝拉撒。