Maison >cadre php >Swoole >Présentation du modèle de processus de swoole

Présentation du modèle de processus de swoole

coldplay.xixi
coldplay.xixiavant
2021-04-15 17:54:302923parcourir

Présentation du modèle de processus de swoole

Lorsque nous avons rencontré pour la première fois l'article sur le serveur, nous avons dit que swoole était piloté par les événements. Lors de l'utilisation de swoole, nous avons également réalisé que l'utilisation de swoole est très simple. Il suffit d'enregistrer le rappel correspondant pour traiter notre logique métier.

Cependant, avant de continuer à apprendre swoole, nous devons jeter un autre regard sur le processus opérationnel et le modèle de processus de swoole.

Recommandé (gratuit) : swoole

Nous avons donné une brève introduction au serveur et à la tâche dans les deux premiers articles, et nous en parlerons à propos du serveur plus tard. La création et l'exécution du script sont toutes exécutées sous la CLI, sauf indication contraire, je n'entrerai donc pas dans les détails.

Maintenant, créons un serveur simple à analyser. Le fichier est nommé 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();

Notez qu'ici nous avons sélectionné deux processus de travail et un processus de tâche, n'est-ce pas ? Cela signifie-t-il que la création de ce serveur démarre 3 processus ? Jetons un coup d'oeil

Ouvrez un nouveau terminal et utilisez la commande ps pour voir les résultats

$ 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

Pour faciliter la lecture, certaines données sans importance dans les résultats ps ont été légèrement traitées.

En excluant le dernier résultat (le dernier est la commande ps que nous avons exécutée), nous avons constaté qu'il y a jusqu'à 5 processus similaires en cours d'exécution. D'après notre compréhension, ne devrait-il pas y en avoir 3 ? deux de plus Lequel ?

Vous vous souvenez de la mise en œuvre du multi-processus dont nous avons parlé dans l'article sur le processus/thread ? Lorsque nous parlons de la mise en œuvre du multi-processus, le mode Master-Worker est généralement conçu. Le mode multi-processus par défaut commun de nginx est exactement le même. Bien sûr, le modèle multi-processus par défaut de swoole est également le multi-processus. modèle de processus.

Comparé au modèle Maître-Ouvrier, le modèle de processus de swoole peut être décrit comme Maître-Gestionnaire-Ouvrier. Autrement dit, une couche supplémentaire de processus Manager est ajoutée sur la base de Master-Worker. Cela répond également à la question que nous avons posée au début : pourquoi il y a 5 processus au lieu de 3 processus. (1 Processus Master + 1 Processus Manager + 2 Processus Worker + 1 Processus Tâche)

Comme le dit le proverbe, "l'existence est raisonnable", regardons les raisons pour lesquelles les trois processus de MasterManagerWorker existent.

Le processus Master est un programme multithread. Remarque : selon notre compréhension précédente, plusieurs threads s'exécutent dans le contexte d'un seul processus. En fait, chaque thread d'un même processus a son propre contexte, mais comme ils coexistent dans le même processus, ils le partagent également. y compris son code, ses données, etc.

Revenons et continuons à parler du processus Maître. Le processus Maître est notre processus principal et est en charge de la vie et de la mort. S'il meurt, tout le reste ci-dessous devra être terminé. Processus maître, y compris le thread principal, plusieurs threads Reactor, etc.

Chaque thread a son propre objectif. Par exemple, le thread principal est utilisé pour l'acceptation, le traitement du signal et d'autres opérations, tandis que le thread Reactor est le thread qui gère les connexions TCP, gère les E/S réseau et envoie et reçoit. données.

Expliquez deux points :

  • Acceptez le fonctionnement du thread principal, le serveur de socket utilise souvent accepter pour bloquer, il y a une image lors de l'introduction de la programmation de socket dans la section précédente, vous pouvez prendre un look
  • Traitement du signal, un signal équivaut à un message. Par exemple, le Ctrl+C que nous utilisons souvent envoie en fait un signal SIGINT au thread principal du processus Master, ce qui signifie que vous pouvez y terminer. Il existe de nombreux types de signaux, qui seront suivis plus tard. Il y a aussi une introduction

Habituellement, une fois que le thread principal a géré la nouvelle connexion, il allouera la connexion à un thread Reactor fixe, et ce Reactor le thread sera toujours responsable de la surveillance de ce socket (voir plus loin dans ce qui précède). Le socket est mis à jour vers socket, qui est un fichier utilisé pour la communication inter-réseau avec un autre processus (le fichier peut être lu et écrit). lorsque le socket est lisible, les données seront lues et le fichier sera lu. La requête est affectée au processus de travail, ce qui explique la signification du troisième paramètre $fromId du rappel onReceive dans le processus de travail lorsque nous l'avons introduit pour la première fois. en swoole ; lorsque le socket est accessible en écriture, les données seront envoyées au client TCP.

Utilisez une image pour faire le tri clairement

Alors pourquoi swoole ne peut-il pas avoir une structure de processus maître-travailleur comme Nginx ? Que fait le processus Manager ?

J'étais sur le point de dire ça.

Nous savons que dans le modèle Master-Worker, il n'y a qu'un seul Master. Le Worker est copié du processus parent Master, et il peut y avoir plusieurs processus Worker.

Remarque : sous Linux, le processus parent peut créer un nouveau processus enfant en appelant la fonction fork. Le processus enfant est une copie du processus parent, presque mais pas exactement la même. est que les deux ont leur propre ID de processus indépendant, à savoir PID.

Pour un processus Master multithread, si vous souhaitez plusieurs processus Worker, vous devez effectuer l'opération de fork, mais l'opération de fork est dangereuse. Par conséquent, dans swoole, il existe un processus Manager à temps plein, et le processus. Le processus de gestionnaire est dédié. Responsable du fonctionnement du fork et de la gestion des processus de travail/tâche. En d’autres termes, le processus Manager « nounou » a toute autorité pour gérer la création et le recyclage des processus travailleurs.

通常,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等等。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer