多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 1.9.17 支持异步安全重启特性 [TOC] `1.9.17`版本重构了底层`WorkerStop`的机制,实现了异步安全重启的特性。包括`stop`、`reload`、`max_request`3个特性全部复用了一套代码。都支持了异步安全重启。 之前的版本 Worker进程收到`SIGTERM`、达到`max_request`时,会立即停止服务,这时`Worker`进程内可能仍然有事件监听,这些异步任务将会被丢弃。新版本中会先创建新的`Worker`,旧的`Worker`在完成所有事件之后自行退出。为了防止某些`Worker`一直不退出,底层还增加了一个`30`秒的定时器,在约定的时间内旧`Worker`没有退出,底层会强行终止。 > 可设置`server->max_wait_time`修改`Worker`进程最大等待时间,默认为`30`秒 ## 实现原理 * `Worker`进程收到`SIGTERM`、达到`max_request`时,移除管道监听,立即回调`onWorkerStop`,并通知`Manager`进程。这时当前的`Worker`不会再收到任何客户端请求数据 * `Worker`进程会设置一个`30`秒的超时定时器,实现退出超时 * `Manager`进程收到`Worker`进程的消息后,创建新的`Worker` * 新的`Worker`继续处理客户端请求数据 * 旧的`Worker`会持续触发`onWorkerExit`事件,`PHP`代码可以此事件回调函数中实现清理逻辑 * 旧的`Worker`会持续检测`EventLoop`中的`socket`数量,在没有任何事件监听后退出进程 * 旧的`Worker`在`30`秒内仍然没有完成异步`IO`任务,底层强制终止运行,退出进程 ## 进程退出事件 为了支持异步重启特性,底层新增了一个`onWorkerExit`事件,当旧的`Worker`即将退出时,会持续触发`onWorkerExit`事件,在此事件回调函数中,应用层可以尝试清理某些长连接`Socket` ~~~ $serv->on('WorkerExit', function (swoole_server $serv, $worker_id) { $redisState = $serv->redis->getState(); if ($redisState == Swoole\Redis::STATE_READY or $redisState == Swoole\Redis::STATE_SUBSCRIBE) { $serv->redis->close(); } }); ~~~ ## 设置等待时间 ~~~ $serv->set([ 'max_wait_time' => 60, ]); ~~~ ## 开启方式 onWorkerExit 回调功能需要设置`reload_async = true`才能开启 ~~~ $serv->set(['reload_async' => true]); ~~~