|
導讀網頁的本質就是超級文本標記語言,通過結合使用其他的Web技術(如:腳本語言、公共網關接口、組件等),可以創造出功能強大的網頁。因而,超級文本標記語言是萬維網(Web)編程的基礎,也就是說萬維網是建立... 網頁的本質就是超級文本標記語言,通過結合使用其他的Web技術(如:腳本語言、公共網關接口、組件等),可以創造出功能強大的網頁。因而,超級文本標記語言是萬維網(Web)編程的基礎,也就是說萬維網是建立在超文本基礎之上的。超級文本標記語言之所以稱為超文本標記語言,是因為文本中包含了所謂“超級鏈接”點。 本篇文章給大家帶來的內容是關于Swoole自定義項目初始化事件處理如何實現(代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。最近使用基于 Swoole 開發的 imi 框架 開發項目,碰到一個需求,就是想要做項目初始化處理。當初始化處理完成前,不想讓 Swoole 處理請求。因為可能有一些值沒有加載進來,處理請求極有可能出現問題。 下面給出了思考過程及解決問題的demo代碼。 首先分析了一下,Swoole 是多進程模式運行的,分為 Master、Manager、Worker 進程。 Master 進程就是我們啟動服務的 cli 命令文件所在進程,在這里面初始化有一個問題,這里所有加載的類、全局變量,其它 Worker 進程里都可以使用,無法熱重啟生效。 Manager 進程的情況基本和上面差不多。 那么只有在 Worker 進程做處理了,但如果寫在 WorkerStart 事件里,每個 Worker 進程都會去執行。 WorkerStart 事件定義: function onWorkerStart(swoole_server $server, int $worker_id);$worker_id是一個從0-$worker_num之間的數字,表示這個Worker進程的ID 那這個就好辦了,直接判斷workerid為0的去觸發項目初始化事件。剩下還有一個問題就是,如何在初始化執行完成前,讓所有 Worker 進程暫時都不處理請求。 思考并嘗試了一下,這個問題可以通過協程掛起來解決,demo 代碼如下: <?php
use Swoole\Coroutine;
$http = new swoole_http_server('127.0.0.1', 8080);
$http->on('WorkerStart', function(swoole_http_server $server, $workerId){
$initFlagFile = __DIR__ . '/init.flag';
if(0 === $server->worker_id && (!is_file($initFlagFile) || file_get_contents($initFlagFile) != $server->manager_pid))
{
// 處理項目初始化事件
initApp();
// 寫入文件,保證不再重復觸發項目初始化事件
file_put_contents($initFlagFile, $server->manager_pid);
// 當前worker進程恢復協程
resumeCos();
// 通知其它worker進程
for($i = 1; $i < $server->setting['worker_num']; ++$i)
{
$server->sendMessage('init', $i);
}
}
});
$http->on('PipeMessage', function(swoole_http_server $server, $srcWorkerId, $data) {
if(0 === $srcWorkerId && 'init' === $data && !defined('APP_INITED'))
{
// 其它worker進程恢復協程
resumeCos();
}
});
$http->on('request', function (swoole_http_request $request, swoole_http_response $response) {
// 判斷未初始化完畢,則掛起協程
if(!defined('APP_INITED'))
{
$GLOBALS['WORKER_START_END_RESUME_COIDS'][] = Coroutine::getuid();
Coroutine::suspend();
}
$response->header('content-type', 'text/html;charset=utf-8');
$response->end('IMI 是一款基于 Swoole 開發的協程 PHP 開發框架,擁有常駐內存、協程異步非阻塞IO等優點。官方網站:<a href="https://imiphp.com" target="_blank">https://imiphp.com</a>');
});
$http->start();
/**
* 處理項目初始化事件,比如這里延時5秒,模擬初始化處理
*
* @return void
*/
function initApp()
{
$count = 5;
for($i = 0; $i < $count; ++$i)
{
echo 'initing ', ($i + 1), '/', $count, PHP_EOL;
sleep(1);
}
}
/**
* 恢復協程
*
* @return void
*/
function resumeCos()
{
define('APP_INITED', true);
$coids = $GLOBALS['WORKER_START_END_RESUME_COIDS'] ?? [];
fwrite(STDOUT, 'suspend co count: ' . count($coids) . PHP_EOL);
foreach($coids as $id)
{
Coroutine::resume($id);
}
}通過在 request 事件中判斷是否初始化完畢,如果沒有初始化完成,則掛起當前協程,將協程ID加入全局變量。 當第0個 worker 進程執行完初始化后,通過向其他 worker 進程發送消息,喚醒曾經掛起的協程們,在初始化期間進來的請求,這時候會被執行。 相關推薦: 詳解javascript實現自定義事件_javascript技巧 以上就是Swoole自定義項目初始化事件處理如何實現(代碼)的詳細內容,更多請關注php中文網其它相關文章! 網站建設是一個廣義的術語,涵蓋了許多不同的技能和學科中所使用的生產和維護的網站。 |
溫馨提示:喜歡本站的話,請收藏一下本站!