swoole进程模型 Reactor、manager、Worker、Task的关系

swoole的进程理解是一个有点点烧脑的地方,但是理解了还是简单,官方的文档其实说得比较具体,但是不够直观

自己重新整理下

=============================官方文档=============================== 三种角色分别的职责是:

Reactor线程

负责维护客户端机器的TCP连接、处理网络IO、收发数据 完全是异步非阻塞的模式 全部为C代码,除Start/Shudown事件回调外,不执行任何PHP代码 将TCP客户端发来的数据缓冲、拼接、拆分成完整的一个请求数据包 Reactor以多线程的方式运行 

Worker进程

接受由Reactor线程投递的请求数据包,并执行PHP回调函数处理数据 生成响应数据并发给Reactor线程,由Reactor线程发送给TCP客户端 可以是异步非阻塞模式,也可以是同步阻塞模式 Worker以多进程的方式运行 

Task进程

接受由Worker进程通过swoole_server->task/taskwait方法投递的任务 处理任务,并将结果数据返回给Worker进程 完全是同步阻塞模式 Task以多进程的方式运行 关系

可以理解为reactor就是nginx,worker就是php-fpm。reactor线程异步并行地处理网络请求,然后再转发给worker进程中去处理。reactor和worker间通过IPC方式通信。

swoole的reactor,worker,task_worker之间可以紧密的结合起来,提供更高级的使用方式。

一个更通俗的比喻,假设Server就是一个工厂,那reactor就是销售,帮你接项目订单。而worker就是工人,当销售接到订单后,worker去工作生产出客户要的东西。而task_worker可以理解为行政人员,可以帮助worker干些杂事,让worker专心工作。

底层会为Worker进程、Task进程分配一个唯一的ID 不同的task/worker进程之间可以通过sendMessage接口进行通信

=============================官方文档完===============================

以上是官方的文档的说明

我做点补充,首先为了区分清楚进程,我们对程序做如下的设置

public function onWorkerStart($server, $worker_id)
    {
        if ($worker_id >= $server->setting['worker_num']) {
            swoole_set_process_name('php ' . $argv[0] . ' task');
        } else {
                swoole_set_process_name('php ' . $argv[0] . ' worker'); 
        }
    }

    public function onStart()
    {
        swoole_set_process_name('php : master ');
    }

    public function onManagerStart()
    {
        global $argv;
        swoole_set_process_name('php ' . $argv[0] . ': manager');
    }

这段代码的意思 其实很简答就是给不同的进程重命名,当然我们为了保证能有task进程出现,还需要定义

    $this->server = new swoole_http_server('0.0.0.0', 8002);
    $this->server->set([
        'worker_num' => 12,
        'task_worker_num' => 8,
        'daemonize' => false,
        'log_file' => './log'
    ]);

{PS:这两段代码只是部分截取,需要补充其他程序代码才能运行} 运行之后,我们能看到如下的进程列表

root     14315 12977  0 11:52 pts/2    00:00:00 php sms_server.php: master      
root     14316 14315  0 11:52 pts/2    00:00:00 php sms_server.php: manager
root     14321 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14322 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14323 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14324 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14325 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14326 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14327 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14328 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14329 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14330 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14331 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14332 14316  0 11:52 pts/2    00:00:00 php sms_server.php worker
root     14333 14316  0 11:52 pts/2    00:00:00 php sms_server.php task
root     14334 14316  0 11:52 pts/2    00:00:00 php sms_server.php task
root     14335 14316  0 11:52 pts/2    00:00:00 php sms_server.php task
root     14336 14316  0 11:52 pts/2    00:00:00 php sms_server.php task

我们可以很清楚的看到,因为我们前面重命名了进程的名字,所以我们的进程 有master manager worker task

master其实就是主进程,也就是前面官方文档说的Reactor线程,具体的作用官方的文档说得很清楚了

manager 进程,其实manager进程并没有参与业务执行过程,他的左右只是根据你的配置管理worker进程的数量,死了的拉起来

worker 就是具体做事情的进程了

task 其实就是一个mini的worker,他可以接受worker投递过来的任务

master(收发网络)->worker(执行)->task(worker不想做的分给task)

用一个三俗的比喻吧

master 就是小发廊门口拉客的皮条客,他只负责拉客和送客,有客人来呢,他就把客人送给物理具体做活儿的技师(worker),有技师去服务

技师(worker),比较忙的时候,她有可以把客人,分给其他的比他地位低的,差一点的助理技师(task)去帮他服务,

如果说技师,直接把客人交代给了助理技师,自己直接去接下一个客人,不等助理技师服务完呢,这个是swoole_server->task非阻塞 如果说技师对助理技师的活儿不放心,一直等着助理技师服务完了,再接着去做活儿呢 这个是swoole_server->task 阻塞的task

至于manager呢,其实就是个鸡头罢了,他的任务呢就是保证今天有多少个技师在店里,如果说某个技师中途跑了或者不能上钟了,他就再安排一个

如此这般 介绍完毕

发布于