Home > Article > PHP Framework > Introducing the process model of swoole
When we first met the server article, we said that swoole is event-driven. In the process of using swoole, we also realized that using swoole is very simple. We only need to register the corresponding callback to process our business logic.
However, before continuing to learn swoole, we need to take another look at swoole's operating process and process model.
Recommendation (free): swoole
We have briefly introduced server and task in the first two articles, and we will talk about server later. The creation and execution of the script are all executed under the CLI unless otherwise specified, so I won’t go into details.
Now, we create a simple server to analyze. The file is named server-process.php
$serv = new swoole_server('127.0.0.1', 9501); $serv->set([ 'worker_num' => 2, 'task_worker_num' => 1, ]); $serv->on('Connect', function ($serv, $fd) { }); $serv->on('Receive', function ($serv, $fd, $fromId, $data) { }); $serv->on('Close', function ($serv, $fd) { }); $serv->on('Task', function ($serv, $taskId, $fromId, $data) { }); $serv->on('Finish', function ($serv, $taskId, $data) { }); $serv->start();
Note that here we have selected two worker processes and one task process. Is that right? Does it mean that creating this server starts 3 processes? Let's take a look
Open a new terminal, let's use the ps command to see the results
$ ps aux | grep server-process root 21843 xxx... php server-process.php root 21844 xxx... php server-process.php root 21846 xxx... php server-process.php root 21847 xxx... php server-process.php root 21848 xxx... php server-process.php root 21854 xxx... grep --color=auto server-process
For the convenience of reading, some unimportant data in the ps results have been slightly processed.
Excluding the last result (the last one is the ps command we ran), we found that there were as many as 5 similar processes running. According to our understanding, shouldn't there be 3? Why are there two more Which one?
Remember the implementation of multi-process we talked about in the article Process/Thread? When we talk about the implementation of multi-process, the Master-Worker mode is generally designed. The common default multi-process mode of nginx is exactly the same. Of course, the default multi-process model of swoole is also the multi-process model.
Compared with the Master-Worker model, swoole's process model can be described as Master-Manager-Worker. That is, an additional layer of Manager process is added on the basis of Master-Worker. This also answers the question we raised at the beginning: why there are 5 processes instead of 3 processes. (1 Master process, 1 Manager process, 2 Worker processes, 1 Task process)
As the saying goes, "existence is reasonable", let's take a look at the reasons why the three processes of Master\Manager\Worker exist.
The Master process is a multi-threaded program. Note: According to our previous understanding, multiple threads run in the context of a single process. In fact, each thread in a single process has its own context, but since they coexist in the same process, they also share it. This process, including its code, data, etc.
Let’s come back and continue talking about the Master process. The Master process is our main process and is responsible for the power of life and death. If it dies, everything underneath will have to be finished. Master process, including main thread, multiple Reactor threads, etc.
Each thread has its own purpose. For example, the main thread is used for Accept, signal processing and other operations, while the Reactor thread is the thread that handles tcp connections, handles network IO, and sends and receives data.
Two points to note:
Usually, after the main thread handles the new connection, it will allocate the connection to a fixed Reactor thread, and this Reactor thread will always be responsible for monitoring this socket (socket will be faced later in the above) Updated to socket, which is a file used for cross-network communication with another process. The file can be read and written). In other words, when the socket is readable, the data will be read and the request will be processed. Assigned to the worker process, this also explains the meaning of the third parameter $fromId of the callback onReceive in the worker process when we first introduced it in swoole; when the socket is writable, the data will be sent to the tcp client.
Use a picture to sort it out clearly
Then why can’t swoole have a Master-Worker process structure like Nginx? What does the Manager process do?
I was about to say this.
We know that in the Master-Worker model, there is only one Master, and the Worker is copied from the parent process Master process, and there can be multiple Worker processes.
Note: In Linux, the parent process can create a new child process by calling the fork function. The child process is a copy of the parent process, almost but not exactly the same. The biggest difference between the two is that they both have their own Independent process ID, namely PID.
For a multi-threaded Master process, if you want to have multiple Worker processes, you must fork the operation, but the fork operation is unsafe. Therefore, in swoole, there is a full-time Manager process, and the Manager process is dedicated Responsible for the fork operation and management of worker/task processes. In other words, the "nanny" Manager process has full authority to manage the creation, recycling and other operations of the worker process.
通常,worker进程被误杀或者由于程序的原因会异常退出,Manager进程为了保证服务的稳定性,会重新拉起新的worker进程,意思就是Worker进程你发生意外“死”了,没关系,我自身不“死”,就可以fork千千万万个你。
当然,Master进程和Manager进程我们是不怎么关心的,从前面两篇文章我们了解到,真正实现业务逻辑,是在worker/task进程内完成的。
再来一张图梳理下Manager进程和Worker/Task进程的关系。
再回到我们开篇抛出的的5个进程的问题,ps的结果简直一模一样,有没有办法能区分这5个进程哪个是哪个呢?
有同学要说啦,既然各个进程之间存在父子关系,那我们就可以通过linux的pstree命令查看结果。
$ pstree | grep server-process | | \-+= 02548 manks php server-process.php | | \-+- 02549 manks php server-process.php | | |--- 02550 manks php server-process.php | | |--- 02551 manks php server-process.php | | \--- 02552 manks php server-process.php | \--- 02572 manks grep server-process
注:centos下命令可修改为 pstree -ap | grep server-process
从结果中我们可以看出,进程id等于02548的进程就是Master进程,因为从结构上看就它是“父”嘛,02549是Manager进程,Worker进程和Task进程就是02550、02551和02552了(每个人的电脑上显示的进程id可能不同,但顺序是一致的,依照此模型分析即可)。
我们看到pstree命令也只能得到大致结果,而且在事先不知道的情况下,根本无法区分Worker进程和Task进程。
在swoole中,我们可以在各个进程启动和关闭的回调中去解决上面这个问题。各个进程的启动和关闭?那岂不是又要记住主进程、Manager进程、Worker进程,二三得六,6个回调函数?
是的,不过这6个是最简单也是最好记的,你实际需要了解的可能还要更多。
Master进程: 启动:onStart 关闭:onShutdown Manager进程: 启动:onManagerStart 关闭:onManagerStop Worker进程: 启动:onWorkerStart 关闭:onWorkerStop
提醒:task_worker也会触发onWorkerStart回调。
是不是很好记?那我们就在server-process.php中通过上面这几种回调来实现对各个进程名的修改。
$serv->on("start", function ($serv){ swoole_set_process_name('server-process: master'); }); // 以下回调发生在Manager进程 $serv->on('ManagerStart', function ($serv){ swoole_set_process_name('server-process: manager'); }); $serv->on('WorkerStart', function ($serv, $workerId){ if($workerId >= $serv->setting['worker_num']) { swoole_set_process_name("server-process: task"); } else { swoole_set_process_name("server-process: worker"); } });
注意:因mac下不支持swoole_set_process_name函数,即不能修改进程名,我们换台centos运行下看看结果(实际上你的服务器也不可能是mac)
# ps aux | grep server-process root 27546 xxx... server-process: master root 27547 xxx... server-process: manager root 27549 xxx... server-process: task worker root 27550 xxx... server-process: worker root 27551 xxx... server-process: worker root 27570 xxx... grep --color=auto simple
运行结果谁是谁一目了然,简直了!
有同学傻眼了,说在workerStart回调中写的看不明白,worker进程和task进程怎么区分的?
我来解释一下:在onWorkerStart回调中,$workerId表示的是一个值,这个值的范围是0~worker_num,worker_num是我们的对worker进程的配置,其中0~worker_num表示worker进程的标识,包括0但不包括worker_num;worker_num~worker_num+task_worker_num是task进程的标识,包括worker_num不包括worker_num+task_worker_num。
按照高中学的区间的知识可能更好理解,以我们案例的配置,workerId的值的范围就是[0,2],[0,2)表示worker进程,[2,3)就表示task_worker进程。
swoole的进程模型很重要,本篇掌握不好,后面的理解可能就会有些问题。
我们在onWorkerStart的回调中,用了serv−>setting去获取配置的server信息,在swoole中预留了一些swooleserver的属性,我们可以在回调函数中访问。比如说我们可以用serv−>setting去获取配置的server信息,在swoole中预留了一些swooleserver的属性,我们可以在回调函数中访问。比如说我们可以用serv->connections属性获取当前server的所有的连接,再比如我们可以通过$serv->master_pid属性获取当前server的主进程id等等。
The above is the detailed content of Introducing the process model of swoole. For more information, please follow other related articles on the PHP Chinese website!