swoole reload 平滑重啓小實踐

官方參考: https://wiki.swoole.com/#/server/methods?id=reload

reload() 安全地重啓所有 Worker/Task 進程。

Swoole\Server->reload(bool $only_reload_taskworkrer = false): bool
  • 平滑重啓只對 onWorkerStartonReceive 等在 Worker 進程中 include/require 的 PHP 文件有效
  • Server 啓動前就已經 include/require 的 PHP 文件,不能通過平滑重啓重新加載
  • 對於 Server 的配置即 $serv->set() 中傳入的參數設置,必須關閉 / 重啓整個 Server 纔可以重新加載
  • Server 可以監聽一個內網端口,然後可以接收遠程的控制命令,去重啓所有 Worker 進程

平滑重啓可調用 reload() 方法 或者 執行 kill -USR1 主進程PID 命令來重啓所有worker進程

測試代碼:

reload_test.php

$server = new Swoole\Http\Server("0.0.0.0", 9501);

$server->set(array(
    'worker_num' => 2,
));

// 服務器啓動時執行一次
$server->on('Start', function ($server) {
    echo 'Start' . PHP_EOL;
});

// 服務器啓動時執行一次
$server->on('ManagerStart', function ($server) {
    echo 'ManagerStart' . PHP_EOL;
});

// 每個 Worker 進程啓動或重啓時都會執行
$server->on('WorkerStart', function ($server, $workerId) {
    echo 'WorkerStart - Worker ID: ' . $workerId . PHP_EOL;
    // 測試reload
    include __DIR__ . DIRECTORY_SEPARATOR . 'workerstart.php';
});

$server->on('Connect', function ($server, $fd, $reactorId) {
    echo 'Connect - Worker ID: '. $server->worker_id . ' , fd: ' . $fd . ' , reactorId: ' . $reactorId. PHP_EOL;
});

$server->on('Request', function ($request, $response) use ($server) {

    if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {
        $response->end();
        return;
    }

    echo 'Request - Worker ID: '. $server->worker_id . PHP_EOL;
    // 測試reload
    $test = new test();
    echo $test->str ?? 'not include file';

    $act = $request->get['act'] ?? '';
    if ($act == 'reload') {
        echo 'Swoole Reload ...' . PHP_EOL;
        $server->reload();
        echo 'Reload Success' . PHP_EOL;
    }

    $response->header("Content-Type", "text/html; charset=utf-8");
    $response->end("Hello Swoole");
});

$server->start();

workerstart.php

class test
{
    public $str = 'include file: workstart.php' . PHP_EOL;
}

啓動服務
php reload_test.php

Start
ManagerStart
WorkerStart - Worker ID: 0
WorkerStart - Worker ID: 1
include file: workstart
include file: workstart

可以看到輸出兩行 include file: workstart, 因爲worker_num設置爲2, 有2個worker進程
此時打開瀏覽器, 訪問 http://127.0.0.1:9501

Connect - Worker ID: 0 , fd: 1 , reactorId: 0
Request - Worker ID: 0
include file: workstart.php

然後修改 workerstart.php 文件中變量 $strinclude file: test.php, 再次訪問 http://127.0.0.1:9501
依舊輸出 include file: workstart.php

Connect - Worker ID: 0 , fd: 2 , reactorId: 0
Request - Worker ID: 0
include file: workstart.php

訪問 http://127.0.0.1:9501?act=reload 觸發代碼 $server->reload() 或者 執行命令 kill -USR1 主進程PID, 讓程序重新 include 文件達到平滑重啓的效果

Swoole Reload ...
[2020-05-12 20:56:41 $131.0]    INFO    Server is reloading all workers now
Reload Success
WorkerStart - Worker ID: 0
WorkerStart - Worker ID: 1

再次訪問 http://127.0.0.1:9501, 看到更新成功, 輸出 include file: test.php

Connect - Worker ID: 0 , fd: 4 , reactorId: 0
Request - Worker ID: 0
include file: test.php





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章