摘要:在版本中我們將的進程管理模塊封裝成了類,現(xiàn)在可以在代碼中使用的進程管理器了。提供的進程管理器來自于,經(jīng)過大量生產(chǎn)項目驗證,穩(wěn)定性和健壯性都非常高。三任務投遞進程管理器自帶了消息隊列和消息投遞的支持。
在Swoole-2.1.2版本中我們將Server的進程管理模塊封裝成了PHP類,現(xiàn)在可以在PHP代碼中使用Swoole的進程管理器了。
在實際項目中經(jīng)常需要寫一些長期運行的腳本,如基于redis、kafka、rabbitmq實現(xiàn)的多進程隊列消費者,多進程爬蟲等等。程序員需要使用pcntl和posix相關的擴展庫實現(xiàn)多進程編程,需要開發(fā)者具備深厚的Linux系統(tǒng)編程功底,否則很容易出現(xiàn)問題。
Swoole提供的進程管理器來自于SwooleServer,經(jīng)過大量生產(chǎn)項目驗證,穩(wěn)定性和健壯性都非常高。可大大簡化多進程腳本編程工作。
一、 創(chuàng)建進程池在PHP代碼中使用new SwooleProcessPool即可創(chuàng)建一個進程池,構造方法的第一個參數(shù)傳入工作進程的數(shù)量。使用on方法設置WorkerStart即可在工作進程啟動時執(zhí)行指定的代碼,可以在這里進行while(true)循環(huán)從redis隊列中獲取任務并處理。使用start方法啟動所有進程,管理器開始進入wait狀態(tài)。
$workerNum = 10; $pool = new SwooleProcessPool($workerNum); $pool->on("WorkerStart", function ($pool, $workerId) { echo "Worker#{$workerId} is started "; $redis = new Redis(); $redis->pconnect("127.0.0.1", 6379); $key = "key1"; while (true) { $msgs = $redis->brpop($key, 2); if ( $msgs == null) continue; var_dump($msgs); } }); $pool->on("WorkerStop", function ($pool, $workerId) { echo "Worker#{$workerId} is stopped "; }); $pool->start();
使用進程管理器,可以保證工作進程的穩(wěn)定性。
某個工作進程遇到致命錯誤、主動退出時管理器會進行回收,避免出現(xiàn)僵尸進程
工作進程退出后,管理器會自動拉起、創(chuàng)建一個新的工作進程
二、信號處理Swoole進程管理器自帶了信號處理,向管理器進程發(fā)送:
SIGTERM信號:中止服務,向所有工作進程發(fā)送SIGTERM關閉進程
SIGUSR1信號:重啟工作進程,管理器會逐個重啟工作進程
在工作進程中可以配合使用pcntl_signal和pcntl_signal_dispatch實現(xiàn)信號處理。
$pool->on("WorkerStart", function ($pool, $workerId) { $running = true; pcntl_signal(SIGTERM, function () use (&$running) { $running = false; }); echo "Worker#{$workerId} is started "; $redis = new Redis(); $redis->pconnect("127.0.0.1", 6379); $key = "key1"; while ($running) { $msgs = $redis->brpop($key, 2); pcntl_signal_dispatch(); if ( $msgs == null) continue; var_dump($msgs); } });三、任務投遞
Swoole進程管理器自帶了消息隊列和TCP-Socket消息投遞的支持。可設置監(jiān)聽系統(tǒng)隊列或者TCP端口,接收任務數(shù)據(jù)。此項功能是可選的,要使用任務投遞功能,需要對進程池對象設置onMessage回調(diào)。
消息隊列$pool = new SwooleProcessPool(2, SWOOLE_IPC_MSGQUEUE, 0x7000001); $pool->on("WorkerStart", function ($pool, $workerId) { echo "Worker#{$workerId} is started "; }); $pool->on("Message", function ($pool, $message) { echo "Message: {$message} "; }); $pool->start();
需要在構造方法的第二個參數(shù)傳入SWOOLE_IPC_MSGQUEUE,第三個參數(shù)設置監(jiān)聽的消息隊列KEY。其他程序中使用消息隊列相關API就可以向工作進程投遞任務了。
TCP 端口$pool = new SwooleProcessPool(2, SWOOLE_IPC_SOCKET); $pool->on("WorkerStart", function ($pool, $workerId) { echo "Worker#{$workerId} is started "; }); $pool->on("Message", function ($pool, $message) { echo "Message: {$message} "; }); $pool->listen("127.0.0.1", 8089); $pool->start();
使用TCP端口監(jiān)聽,需要設置構造方法的第二個參數(shù)為SWOOLE_IPC_SOCKET,并使用listen方法設置監(jiān)聽的主機和端口。
底層使用了4字節(jié)長度+包體的協(xié)議。其他程序中向此端口發(fā)送數(shù)據(jù)時,需要在數(shù)據(jù)包之前增加一個長度字段。
$fp = stream_socket_client("tcp://127.0.0.1:8089", $errno, $errstr) or die("error: $errstr "); $msg = json_encode(["data" => "hello", "uid" => 1991]); fwrite($fp, pack("N", strlen($msg)).$msg); fclose($fp);
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/28568.html
摘要:請求的多階段異步處理多階段異步處理請求與事件驅(qū)動架構是密切相關的,也就是說,請求的多階段異步處理只能基于事件驅(qū)動架構實現(xiàn)。 前言 最近在讀 Nginx 相關的書籍,做一下讀書筆記。 Nginx 作為業(yè)界知名的高性能服務器,被廣泛的應用。它的高性能正是由于其優(yōu)秀的架構設計,其架構主要包括這幾點:模塊化設計、事件驅(qū)動架構、請求的多階段異步處理、管理進程與多工作進程設計、內(nèi)存池的設計,以下內(nèi)...
摘要:請求的多階段異步處理多階段異步處理請求與事件驅(qū)動架構是密切相關的,也就是說,請求的多階段異步處理只能基于事件驅(qū)動架構實現(xiàn)。 前言 最近在讀 Nginx 相關的書籍,做一下讀書筆記。 Nginx 作為業(yè)界知名的高性能服務器,被廣泛的應用。它的高性能正是由于其優(yōu)秀的架構設計,其架構主要包括這幾點:模塊化設計、事件驅(qū)動架構、請求的多階段異步處理、管理進程與多工作進程設計、內(nèi)存池的設計,以下內(nèi)...
摘要:限制同時運行線程數(shù)使用類就行,在內(nèi)部管理著一個計數(shù)器。當計數(shù)器到時,再調(diào)用就會阻塞,直到其他線程來調(diào)用,這樣就限制了同時運行線程的數(shù)量。 事前最好了解一下什么是進程,什么是線程,什么是GIL,本文不再贅述,直接介紹模塊的使用: 推薦1,推薦2,推薦3,更多自尋 普通的python爬蟲是單進程單線程的,這樣在遇到大量重復的操作時就只能逐個進行,我們就很難過了。舉個栗子:你有1000個...
閱讀 1311·2021-11-24 10:24
閱讀 4088·2021-11-22 15:29
閱讀 1085·2019-08-30 15:53
閱讀 2788·2019-08-30 10:54
閱讀 1977·2019-08-29 17:26
閱讀 1271·2019-08-29 17:08
閱讀 605·2019-08-28 17:55
閱讀 1576·2019-08-26 14:01