Server->reload
最后更新于:2022-04-02 06:19:56
# Server->reload
[TOC]
重启所有`Worker/Task`进程。
~~~
bool Server->reload(bool $only_reload_taskworkrer = false)
~~~
* `$only_reload_taskworkrer`是否仅重启`Task`进程
一台繁忙的后端服务器随时都在处理请求,如果管理员通过`kill`进程方式来终止/重启服务器程序,可能导致刚好代码执行到一半终止。
这种情况下会产生数据的不一致。如交易系统中,支付逻辑的下一段是发货,假设在支付逻辑之后进程被终止了。会导致用户支付了货币,但并没有发货,后果非常严重。
`Swoole`提供了柔性终止/重启的机制,管理员只需要向`Server`发送特定的信号,`Server`的`Worker`进程可以安全的结束。
* `SIGTERM`: 向主进程/管理进程发送此信号服务器将安全终止
* 在`PHP`代码中可以调用`$serv->shutdown()`完成此操作
* `SIGUSR1`: 向主进程/管理进程发送`SIGUSR1`信号,将平稳地`restart`所有`Worker`进程
* 在`PHP`代码中可以调用`$serv->reload()`完成此操作
* `reload`有保护机制,当一次`reload`正在进行时,收到新的重启信号会丢弃
* 如果设置了`user/group,Worker`进程可能没有权限向master进程发送信息,这种情况下必须使用`root`账户,在`shell`中执行`kill`指令进行重启
* `reload`指令对`addProcess`添加的用户进程无效
~~~
#重启所有worker进程
kill -USR1 主进程PID
~~~
1.7.7版本增加了仅重启task\_worker的功能。只需向服务器发送SIGUSR2即可。
~~~
#仅重启task进程
kill -USR2 主进程PID
~~~
> 平滑重启只对`onWorkerStart`或`onReceive`等在`Worker`进程中`include/require`的`PHP`文件有效,`Server`启动前就已经`include/require`的`PHP`文件,不能通过平滑重启重新加载
> 对于`Server`的配置即`$serv->set()`中传入的参数设置,必须关闭/重启整个`Server`才可以重新加载
> `Server`可以监听一个内网端口,然后可以接收远程的控制命令,去重启所有`Worker`进程
## Process模式
在`Process`模式下,来自客户端的`TCP`连接是在`Master`进程内维持的,`worker`进程的重启和异常退出,不会影响连接本身。
## Reload有效范围
`Reload`操作只能重新载入`Worker`进程启动后加载的`PHP`文件,建议使用`get_included_files`函数来列出哪些文件是在`WorkerStart`之前就加载的`PHP`文件,在此列表中的`PHP`文件,即使进行了`reload`操作也无法重新载入。比如要关闭服务器重新启动才能生效。
~~~
$serv->on('WorkerStart', function($serv, $workerId) {
var_dump(get_included_files()); //此数组中的文件表示进程启动前就加载了,所以无法reload
});
~~~
## APC/OpCache
如果`PHP`开启了`APC/OpCache`,`reload`重载入时会受到影响,有`2`种解决方案
* 打开`APC/OpCache`的`stat`检测,如果发现文件更新`APC/OpCache`会自动更新`OpCode`
* 在`onWorkerStart`中执行`apc_clear_cache`或`opcache_reset`刷新`OpCode`缓存
## 参考
* [附录:Linux信号列表](https://wiki.swoole.com/wiki/page/158.html)
';