正确重启Swoole服务需先优雅关闭再启动:用kill -15主进程PID触发onShutdown,确认退出后重新执行启动命令;reload仅重载worker进程,不生效于配置变更。

如何正确重启 Swoole 服务(非 reload)
直接 kill 进程再启动,是多数人踩坑的起点。Swoole 的 swoole_http_server 或 swoole_websocket_server 启动后会 fork 多个子进程,仅用 kill -9 主进程 PID 很可能留下 worker 进程残留,导致端口被占、新实例起不来。
真正安全的重启分两步:先优雅关闭,再重新启动。
- 查主进程 PID:
ps aux | grep 'php.*server.php' | grep -v grep | awk '{print $2}' | head -1 - 发 SIGTERM(不是 SIGKILL):
kill -15 <pid>—— 这会触发onShutdown回调,释放资源、关闭连接 - 确认进程退出:
ps -p <pid>返回空则完成;若超时未退,再补kill -9 - 重新执行启动命令,例如:
php server.php start
swoole_reload 不等于重启,它只重载 worker 进程
swoole_reload 是 Swoole 提供的热重载机制,但它只对 worker 进程有效,manager、master、task_worker 等进程不会重启。这意味着:配置变更(如 worker_num、task_worker_num)、扩展加载、全局常量定义等,reload 后完全不生效。
常见误用场景:改了 server->set() 参数后执行 kill -USR1,发现没变化——因为 set 配置只在 new 实例时读取一次。
- 适用 reload 的只有 PHP 业务代码逻辑更新(如路由处理函数、控制器方法)
- 信号必须发给 master 进程 PID,不是 worker PID
- 需确保
reload_async = true(默认开启),否则 reload 会阻塞请求 - 若启用了 opcache,记得清掉:
opcache_reset()或重启 php-fpm(如果混用)
systemd 管理 Swoole 时 restart 失败的典型原因
用 systemctl restart swoole-server.service 却卡住或报 Failed to restart,大概率是 service 文件没写对。Swoole 进程默认以 daemon 模式运行,而 systemd 要求主进程前台驻留(即不能 fork 到后台)。
关键点:必须设置 daemonize = false,并让 PHP 脚本不 exit,否则 systemd 会认为服务已“结束”。
- PHP 启动脚本末尾不能有
exit或die,server 实例要保持运行 - service 文件里加
Type=simple(不是 forking),并设Restart=always - 日志看失败原因:
journalctl -u swoole-server -n 50 -f,常见错误是Address already in use(上一进程没彻底退出) - 避免在
ExecStart里加&或nohup,systemd 自己管进程生命周期
docker 中重启 Swoole 容器为何总连不上?
Docker 容器内 Swoole 绑定 0.0.0.0:9501 没问题,但宿主机 curl localhost:9501 失败,往往不是重启问题,而是网络或启动时机问题。
Swoole 启动需要时间初始化 reactor、acceptor 等,容器刚 start 就立刻发请求,大概率 502/Connection refused。
- 在 docker-compose.yml 中加
healthcheck,用curl -f http://localhost:9501/ping || exit 1 - 避免使用
restart: always+daemonize = true组合,会导致容器内多个 Swoole 实例争抢端口 - entrypoint 脚本中不要用
sleep 2硬等,应检测端口就绪:while ! nc -z 127.0.0.1 9501; do sleep 0.5; done - 镜像里 PHP 版本和 Swoole 扩展版本必须严格匹配,
php --ri swoole输出中若有undefined symbol,重启也白搭









