关于Swoole中内存共享和热重启

来源:互联网 发布:agile plm java被停止 编辑:程序博客网 时间:2024/06/14 11:36

热重启的基本业务逻辑是,将变动性大的业务逻辑加载过程放在OnWorkerStart方法中。

涉及到进程模型:


OnWorkerStart之后加载的代码都在各自进程中,OnWorkerStart之前加载的代码属于共享内存。

OnWorkerStart会由Worker或TaskWorker进程触发,区分是Worker进程还是Task进程的方法是:

if($worker_id >= $serv->setting['worker_num']) {   //这个是Task进程    require_once __DIR__ . '/App/Handler/HeartBeatHandler.php';    $hand = new HeartBeatHandler();    $this->AddEventHandler($hand);} else {  //这个是Worker进程}

由此产生的问题的问题是,各个Worker或者Task进程New出来的对象是不共享的。

而OnTask事件是在Task进程中触发的,OnReceive等事件是在Worker进程中触发的。

在上例中,在所有的Task进程中的$this对象都添加了新的Handler,这些Handler在OnReceive事件中是访问不到的,因为OnReceive事件是在Worker进程中触发的。

相对的,如果想在OnReceive中访问这些Handler,则应该在Worker进程中添加。

如果通过worker_id细分到各个进程,则各个进程内部创建的对象都是不共享的。

如果希望全局共享,则应该在OnStart或者之前添加。

当然,这里既然涉及到了热重启,则需要通过kill -10命令Master进程执行Server_Reload方法,此方法会在Worker进程完成当前任务后重启,并触发OnWorkerStop事件。

在上例中,应在OnWorkerStop事件中清除已有的Handler,释放内存空间。然后会再度触发OnWorkerStart事件,实现Handler的代码热更新。

function OnWorkerStop(\swoole_server $server, $worker_id){    if ($worker_id >= $server->setting['worker_num'])//worker的进程,其他的是Task_Worker的进程    {        DILog("Worker Stop {$worker_id}"."/Count".count($this->handlerArray));        $this->handlerArray = [];    }}


参考手册:

http://wiki.swoole.com/wiki/page/46.html

可以将公用的,不易变的php文件放置到onWorkerStart之前。这样虽然不能重载入代码,但所有worker是共享的,不需要额外的内存来保存这些数据。onWorkerStart之后的代码每个worker都需要在内存中保存一份

PS:为了更灵活,应将加载Handler的代码改成通过反射被动加载的方式。


0 0
原创粉丝点击