reload_async=true时,worker进程等待异步任务完成后才退出,避免请求中断;但需满足swoole≥4.8.13、daemonize=false、onworkerstart无阻塞操作三条件才生效。

reload_async 开启与否,直接决定热重启时「新请求是否被阻塞」——开则不阻塞,关则会卡住,但前提是它真能生效。很多人的配置写了 reload_async => true 却没效果,不是参数没用,而是运行环境或配置链路断了。
reload_async = true 时到底发生了什么
主进程收到 SIGUSR1(或 systemctl reload)后,并不立即杀掉 worker,而是发信号让每个 worker 自行判断:当前有没有未完成的异步任务(如协程中未结束的 curl_exec、mysql_query、文件 I/O 等)。只有等所有异步操作自然结束,worker 才退出并被新进程替换。
- 适用于长连接服务(WebSocket、RPC)、带数据库/HTTP 客户端调用的业务逻辑
- 依赖底层协程调度器的「退出感知」能力,Swoole ≥ 4.8.13 才修复了旧版的竞态 bug
- 若 worker 正在执行阻塞操作(比如没设超时的
file_get_contents),它不会响应退出信号,整个 reload 就卡在waiting for worker exit
reload_async = false 的实际表现
这是默认行为(注意:Swoole 4.8.13+ 默认值是 true,但很多框架如 Think-Swoole 在初始化时硬编码为 true,而旧项目可能仍沿用老默认)。worker 收到信号后立刻终止,不管当前协程是否跑完——相当于「暴力杀进程」。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 可能导致正在处理的请求直接中断,客户端收到 Connection reset 或空响应
- 适合纯计算型、无外部 I/O、且对一致性要求不高的场景(比如内部定时任务服务)
- 即使设为
false,若daemonize = true,主进程也收不到SIGUSR1,reload 根本不会触发
为什么你设了 true 却没生效
不是代码写错,而是三个硬性条件缺一不可:
- Swoole 版本必须 ≥ 4.8.13;低于此版本存在信号竞争,
reload_async形同虚设 -
daemonize必须为false;若要用守护模式,得靠 systemd 配置ReloadSignal=SIGUSR1,不能靠 PHP 层自己 fork -
onWorkerStart中不能有阻塞操作;比如未加timeout的curl_init+curl_exec,会让 worker 卡死在启动阶段,后续任何 reload 都无法推进
生产环境要不要开 reload_async
要看你是否承受得起「一次 reload 多等几秒」。开启它确实让热更新更安全,但也带来两个隐性成本:
- 如果某个 worker 死循环或协程泄漏,它永远不会退出,整个 reload 就一直 hang 住,得靠
max_wait_time强制超时(但超时后该 worker 会被 SIGKILL,仍不优雅) - 和
inotify_mode一起用(开发期常见)会放大风险;生产必须关掉inotify_mode,否则文件监听本身就会干扰信号处理 - 某些框架(如 Think-Swoole)把
reload_async写死在启动逻辑里,你改配置文件根本无效,得用事件钩子重设
最常被忽略的一点:reload_async 的作用域仅限于 worker 进程重启,它不影响 task 进程、manager 进程或主进程。如果你的业务逻辑大量依赖 task_worker,记得同步检查 task_max_request 和 task_enable_coroutine 的配合是否合理。










