Swoole平滑重启

Swoole平滑重启

author: he xiaodong date: 2019-02-25

借助 swoole 的特性实现的热重启

很多时候,业务代码修改了一点,而swoole正在处理一些逻辑,直接强行结束 swoole 进程,然后重启可能造成不可预知的问题和脏数据, swoole 自身提供了热重启方法,不需要结束进程进行重启,但也有一些局限性:

Reload 操作只能重新载入 Worker 进程启动后加载的 PHP 文件,建议使用get_included_files 函数来列出哪些文件是在 WorkerStart 之前就加载的 PHP 文件,在此列表中的 PHP 文件,即使进行了 reload 操作也无法重新载入。比如要关闭服务器重新启动才能生效。平滑重启只会重启worker及task进程部分,不会重启master进程。

实现方法如下:

被引入的文件 reload.php

<?php
    function test()
    {
        echo '之前' . PHP_EOL;
    }

测试代码 swoole-reload.php

<?php
$server = new swoole_websocket_server("0.0.0.0", 9502);

$server->set([
    'worker_num' => 2,
    'daemonize' => false,
    'max_request' => 10000,
    'dispatch_mode' => 2,
    'debug_mode'=> 1
]);

$server->on('start', function ($server) {
    cli_set_process_title("swoole");
});

$server->on('workerStart', function ($server, $workerId) {
    require_once 'reload.php';
    test();
    echo '哈' . PHP_EOL;
});

$server->on('message', function (swoole_websocket_server $server, $request) {
    $server->push($request->fd, "hello");
});

$server->start();

热重启脚本文件 reload.sh 创建之后记得加上执行权限

echo "Reloading..."
cmd=$(pidof reload_master)

kill -USR1 "$cmd"  # 重启所有 worker 进程
#kill -USR2 "$cmd"  # 仅重启 task 进程
echo "Reloaded"

操作过程:执行 php swoole-reload.php 开启 swoole 进程,次数会输出两次 之前 哈,对应着配置的 worker_num 数量,然后新起终端,修改 reload.php, 将 echo 的信息改为 之后,’./reload.sh’,会在 swoole 终端输出 notice 信息及两次 之后 哈,效果如图:

Swoole 平滑重启

参考链接:

  1. Swoole reload 文档