Swoole自定义项目初始化事件处理的实现-php教程

资源魔 73 0
比来应用基于 Swoole 开发的 imi 框架开发名目,碰着一个需要,就是想要做名目初始化解决。当初始化解决实现前,没有想让 Swoole 解决申请。由于可能有一些值不加载出去,解决申请极有可能呈现成绩。

上面给出了考虑进程及处理成绩的demo代码。

起首剖析了一下,Swoole 是多过程模式运转的,分为 MasterManagerWorker 过程。

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 过程发送音讯,叫醒已经挂起的协程们,正在初始化时期出去的申请,这时候候会被执行。

以上就是Swoole自界说名目初始化事情解决的完成的具体内容,更多请存眷资源魔其它相干文章!

标签: php php开发教程 php开发资料 php开发自学 Swoole

抱歉,评论功能暂时关闭!