关于优雅退出的问题及解决方案

kyo

如何实现优雅退出呢

由于项目上需要在业务执行完成后才退出,本人的实现方式是在一个叫master的子进程中监听业务进程,在所有业务完成后再退出master的子进程,但由于框架的退出时是不分次序直接退出,导致业务进程还在执行,而master的子进程已经退出,无法完成完整业务

本人在做优雅退出时是通过重写stopAII实现,测试发现派生的子类的stopAII并未执行,检查过框架源码理应能正常执行,能否帮忙看看呢

public static function stopAll($code = 0, $log = '') {
    Log::info('child Worker', 'stopAll');

    if (\DIRECTORY_SEPARATOR === '/' && static::$_masterPid === posix_getpid()) {
        Log::info('master', 'stopAll');
        parent::stopAll($code, $log);
    } else {
        if ($log) {
            static::log($log);
        }
        static::$_status = static::STATUS_SHUTDOWN;
        // Execute exit.
        $workers = array_reverse(static::$_workers);
        foreach ($workers as $worker) {
            if (!$worker->stopping) {
                $worker->stop();
                $worker->stopping = true;
            }
        }
        if (!static::$_gracefulStop) {
            static::$_workers = array();
            if (static::$globalEvent) {
                static::$globalEvent->destroy();
            }
            try {
                Log::info('exit Worker', '111111111111');
                exit($code);
            } catch (\Exception $e) {
            }
        }
    }
}

能否在框架层面增加类似reload的逐个退出,同时可以定义退出的顺序(能提供是最好的)

或者这个退出判断能否加个自定义的回调来控制

if (!static::$_gracefulStop|| ConnectionInterface::$statistics['connection_count’]<=0)

又或者能否解决到子类的stopAlI无法触发的问题

@walkor

155 2 0
2个回答

按照你的需求不用那么麻烦,代码里设置

// 默认2秒
Worker::$stopTimeout = 600;

这样所有子进程会一直等待所有阻塞业务执行完毕才退出,最多等600秒。

  • kyo 1天前

    这个不是只在普通退出才有用吗?且测试过的确无法满足需求,按照框架目前的优雅退出只能满足各进程无任何关联,就像一个请求上来开一个进程处理即可,但本人的需求则是进程间是有数据交互的,需要控制好进程的退出顺序

子进程调用 stopAll() 只是停止自己(当前子进程)。
主进程调用 stopAll() 是停止所有进程。
子进程可以通过调用

posix_kill(posix_getppid(), SIGINT);

来触发主进程调用 stopAll()

  • 暂无评论
🔝