搜尋
首頁php框架Swoole介紹swoole之進程模型

介紹swoole之進程模型

Apr 15, 2021 pm 05:54 PM
swoole

介紹swoole之進程模型

初識server一文的時候我們說過,swoole是事件驅動的。在使用swoole的過程中,我們也體會到,swoole的使用非常簡單,僅僅註冊相應的回調處理我們的業務邏輯即可。

但是,在繼續學習swoole之前,我們有必要再看一看swoole的運行流程和進程模型。

推薦(免費):swoole

#前面兩篇文章我們已經對server和task做了簡單的介紹,後面再對server的創作以及腳本的執行,如無特殊說明均在CLI下執行,我就不囉嗦了。

現在,我們建立一個簡單的server來分析一下,檔案命名為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();

注意這裡我們選擇了兩個worker進程個一個task進程,那是不是就代表創建這個server就是開啟了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個嗎,怎麼多了兩個呢?

還記得我們在進程/執行緒一文中說過的多進程的實作嗎?我們說到多進程的實作一般會被設計Master-Worker模式,常見的nginx預設的多進程模式也正是如此,當然swoole預設的也是多進程模型。

比較Master-Worker模式,swoole的行程模型可以用Master-Manager-Worker來形容。即在Master-Worker的基礎上又增加了一層Manager進程。這也就解答了我們開頭拋出的問題為什麼是5個行程而不是3個行程了。 (1個Master進程 1個Manager進程 2個Worker進程 1個Task進程)

正所謂“存在即合理”,我們來看看Master\Manager\Worker三種進程各自存在的原因。

Master程序是一個多執行緒程式。註解:按照我們先前的理解,多個執行緒是運行在單一進程的上下文中的,其實對於單一進程中的每一個線程,都有它自己的上下文,但是由於共同存在於同一進程,所以它們也共享這個進程,包括它的程式碼、資料等等。

再回來繼續說Master進程,Master進程就是我們的主進程,掌管生殺大權,它掛了,那底下的都得玩完。 Master進程,包含主線程,多個Reactor線程等。

每一個執行緒都有自己的用途,例如主執行緒用於Accept、訊號處理等操作,而Reactor執行緒是處理tcp連接,處理網路IO,收發資料的執行緒。

說明兩點:

  • 主執行緒的Accept操作,socket服務端常用accept阻塞,上一節介紹socket程式的時候有一個配圖,可以看看
  • 訊號處理,訊號就相當於一則訊息,例如我們常操作的Ctrl C其實就是給Master進程的主執行緒發送一個SIGINT的訊號,意思是你可以終止啦,訊號有很多種,後面還有介紹

通常,主線程處理完新的連接後,會將這個連接分配給固定的Reactor線程,並且這個Reactor線程會一直負責監聽此socket(上文中後面對socket更新為socket即套接字,是用來與另一個進程進行跨網路通訊的文件,文件可讀可寫),換句話說當此socket可讀時,會讀取數據,並將該請求分配給worker進程,這也解釋了我們在swoole初識講解worker進程內的回調onReceive的第三個參數$fromId的含義;當此socket可寫時,會把數據發送給tcp客戶端。

用一張圖清晰的梳理下

那swoole為啥不能像Nginx一樣,是Master-Worker進程結構的呢? Manager進程是乾啥的?

這個我正準備說。

我們知道,在Master-Worker模型中,Master只有一個,Worker是由父程序Master進程複製出來的,且Worker進程可以有多個。

註解:在linux中,父進程可以透過呼叫fork函數來建立一個新的子進程,子進程是父進程的一個副本,幾乎但不完全相同,二者的最大差異就是都擁有自己獨立的進程ID,即PID。

對於多執行緒的Master進程而言,想要多Worker進程就必須fork操作,但是fork操作是不安全的,所以,在swoole中,有一個專職的Manager進程,Manager進程就專門負責worker/task流程的fork操作與管理。換句話說,對於worker進程的建立、回收等操作全權有「保姆」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等等。

以上是介紹swoole之進程模型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器