layout: posttitle: Swoole平滑重启
subtitle: Swoole平滑重启
date: 2019-02-25
author: he xiaodong
header-img: img/default-post-bg.jpg
catalog: true
tags:
- PHP
- Swoole reload
- Swoole 平滑重启

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

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

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

实现方法如下:

被引入的文件 reload.php

  1. <?php
  2. function test()
  3. {
  4. echo '之前' . PHP_EOL;
  5. }

测试代码 swoole-reload.php

  1. <?php
  2. $server = new swoole_websocket_server("0.0.0.0", 9502);
  3. $server->set([
  4. 'worker_num' => 2,
  5. 'daemonize' => false,
  6. 'max_request' => 10000,
  7. 'dispatch_mode' => 2,
  8. 'debug_mode'=> 1
  9. ]);
  10. $server->on('start', function ($server) {
  11. cli_set_process_title("swoole");
  12. });
  13. $server->on('workerStart', function ($server, $workerId) {
  14. require_once 'reload.php';
  15. test();
  16. echo '哈' . PHP_EOL;
  17. });
  18. $server->on('message', function (swoole_websocket_server $server, $request) {
  19. $server->push($request->fd, "hello");
  20. });
  21. $server->start();

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

  1. echo "Reloading..."
  2. cmd=$(pidof reload_master)
  3. kill -USR1 "$cmd" # 重启所有 worker 进程
  4. #kill -USR2 "$cmd" # 仅重启 task 进程
  5. echo "Reloaded"

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

2019-02-25-Swoole平滑重启 - 图1

参考链接:

  1. Swoole reload 文档

最后恰饭 阿里云全系列产品/短信包特惠购买 中小企业上云最佳选择 阿里云内部优惠券