ホームページ  >  記事  >  PHPフレームワーク  >  スウールのプロセスモデルの紹介

スウールのプロセスモデルの紹介

coldplay.xixi
coldplay.xixi転載
2021-04-15 17:54:302871ブラウズ

スウールのプロセスモデルの紹介

私たちが最初にサーバーの記事に出会ったとき、swoole はイベント駆動型であると言いました。 swoole を使用する過程で、swoole の使用は非常に簡単で、ビジネス ロジックを処理するために対応するコールバックを登録するだけでよいことにも気づきました。

ただし、swoole の学習を続ける前に、swoole の操作プロセスとプロセス モデルをもう一度見てみる必要があります。

推奨事項 (無料): swoole

最初の 2 つの記事でサーバーとタスクについて簡単に紹介しました。サーバーについては後ほど説明します。特に指定がない限り、スクリプトの作成と実行はすべて CLI で実行されるため、詳細は説明しません。

ここで、分析する単純なサーバーを作成します。ファイルの名前は、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();

ここでは、2 つのワーカー プロセスと 1 つのタスク プロセスを選択していることに注意してください。このサーバーを作成すると3つのプロセスが開始されるということでしょうか?見てみましょう

新しいターミナルを開いて、ps コマンドを使用して結果を確認してみましょう

$ 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

読みやすいように、ps 結果内の重要でないデータの一部がわずかに処理されています。

最後の結果 (最後に実行した ps コマンド) を除くと、同様のプロセスが 5 つも実行されていることがわかりました。私たちの理解によれば、3 つあるはずではありませんか? なぜ存在するのでしょうか?あと2つどれですか?

「プロセス/スレッド」の記事で説明したマルチプロセスの実装を覚えていますか?マルチプロセスの実装について話すとき、マスター-ワーカー モードが一般的に設計されています。nginx の一般的なデフォルトのマルチプロセス モードもまったく同じです。もちろん、swoole のデフォルトのマルチプロセス モデルもマルチプロセスです。プロセスモデル。

マスター-ワーカー モデルと比較すると、swoole のプロセス モデルはマスター-マネージャー-ワーカーとして説明できます。つまり、Master-Worker に基づいて Manager プロセスの追加レイヤーが追加されます。これは、最初に提起した質問、つまりなぜ 3 つのプロセスではなく 5 つのプロセスがあるのか​​という質問にも答えます。 (1 マスタープロセス、1 マネージャープロセス、2 ワーカープロセス、1 タスクプロセス)

「存在には合理性がある」という言葉があるように、マスター\マネージャー\ の 3 つのプロセスが存在する理由を見てみましょう。労働者は存在する。

マスター プロセスはマルチスレッド プログラムです。注: これまでの理解によれば、複数のスレッドは 1 つのプロセスのコンテキストで実行されます。実際、1 つのプロセス内の各スレッドは独自のコンテキストを持ちますが、同じプロセス内に共存するため、それも共有します。このプロセスは、そのコード、データなどを含みます。

戻ってマスター プロセスについて話を続けましょう。マスター プロセスは私たちのメイン プロセスであり、生と死の力を担当します。マスター プロセスが終了すると、その下にあるものはすべて完了する必要があります。メイン スレッド、複数の Reactor スレッドなどを含むマスター プロセス。

各スレッドには独自の目的があります。たとえば、メイン スレッドは Accept、信号処理、その他の操作に使用され、Reactor スレッドは TCP 接続の処理、ネットワーク IO の処理、および送受信を行うスレッドです。データ。

注意すべき 2 つの点:

  • メイン スレッドの accept 操作、ソケット サーバーはブロックするために accept をよく使用します。前のセクションでソケット プログラミングを紹介したときの図があります。ご覧ください
  • シグナル処理、シグナルはメッセージに相当します。たとえば、私たちが頻繁に操作する Ctrl C は、実際にはマスター プロセスのメイン スレッドに SIGINT シグナルを送信します。シグナルには多くの種類があり、後ほどさらに詳しく説明します。はじめにがあります

通常、メインスレッドは新しい接続を処理した後、その接続を固定の Reactor スレッドに割り当てます。そして、この Reactor スレッドは常にこのソケットの監視を担当します (ソケットは上記の後半で説明します)。ソケット (別のプロセスとのネットワーク間通信に使用されるファイルです。ファイルは読み書きできます) に更新されます。つまり、ソケットが読み取り可能な場合、データが読み取られ、リクエストが処理されます。これはワーカー プロセスに割り当てられており、最初に導入したときのワーカー プロセスのコールバック onReceive の 3 番目のパラメーター $fromId の意味も説明しています。ソケットが書き込み可能になると、データは TCP クライアントに送信されます。

画像を使用して明確に整理してください

では、なぜ swoole は Nginx のようなマスター ワーカー プロセス構造を持たないのでしょうか? Manager プロセスは何をするのでしょうか?

私はこれを言おうとしていました。

マスター-ワーカー モデルでは、マスターは 1 つだけ存在し、ワーカーは親プロセスのマスター プロセスからコピーされ、複数のワーカー プロセスが存在できることがわかっています。

注: Linux では、親プロセスは fork 関数を呼び出すことで新しい子プロセスを作成できます。子プロセスは親プロセスのコピーであり、ほぼ同じではありますが、まったく同じではありません。この 2 つの最大の違いは、それは、両方とも独自の独立したプロセス ID、つまり PID を持っているということです。

マルチスレッドのマスター プロセスの場合、複数のワーカー プロセスが必要な場合は、操作をフォークする必要がありますが、フォーク操作は安全ではありません。そのため、swoole にはフルタイムのマネージャー プロセスがあります。 Manager プロセスは、フォークの操作とワーカー/タスク プロセスの管理を担当する専用のプロセスです。言い換えれば、「ナニー」マネージャー プロセスは、ワーカー プロセスの作成、リサイクル、その他の操作を管理する完全な権限を持ちます。

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

以上がスウールのプロセスモデルの紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。