Hyperf单机热更新通过端口切换+Nginx流量接管实现滚动更新,无需watcher或k8s;使用双端口(如9501/9502)部署,Nginx upstream动态指向在线端口,脚本自动完成探测、启新、切流、停旧四步,确保不中断服务。

Hyperf 单机环境下实现代码热更新且不中断服务,核心不是“热加载类”,而是通过端口切换 + Nginx 流量接管模拟滚动更新。它不依赖 watcher(那是开发用的),也不需要 k8s 或 Swarm,适合中小团队轻量级生产部署。
准备两个监听端口
选两个固定可用端口(如 9501 和 9502),确保系统未被占用。Hyperf 服务分别绑定不同端口,避免冲突。每次只让一个端口对外提供服务,另一个用于部署新版本。
- 检查端口是否空闲:
netstat -tuln | grep ':950[12]' - 在
config/autoload/server.php中动态配置端口,或通过环境变量控制:'port' => (int)getenv('HYPERF_PORT') ?: 9501 - 启动命令需带端口参数,例如:
php bin/hyperf.php start --port=9501
用 Nginx 做流量调度
Nginx 作为反向代理,只把请求转发给当前“在线”的那个端口。发布时先让新端口就绪,再切流,最后停旧服务。
- 配置 upstream 文件(如
/etc/nginx/conf.d/omsapi_upstream.conf): upstream omsapi { server 127.0.0.1:9501; } - 主 server 块 proxy_pass 指向该 upstream
- 发布脚本修改 upstream 文件,将 server 地址从 9501 改为 9502,再执行
nginx -s reload - reload 后新请求走新端口,已有长连接仍留在旧端口,自然完成过渡
自动化发布脚本关键逻辑
一个 shell 脚本能完成探测、启新、切流、停旧四步,全程无需人工干预。
- 先查当前在线端口(curl 返回 200 的那个)
- 用新端口启动 Hyperf(推荐用 supervisor 或 systemd 管理进程,避免前台阻塞)
- 等待新服务响应正常(轮询 curl 直到返回 200)
- 更新 Nginx upstream 并重载配置
- 延迟 5 秒后停止旧端口对应的服务进程(或容器)
注意事项与避坑点
这个流程看似简单,但几个细节决定是否真“不中断”:
-
健康检查必须真实有效:不能只 ping 端口,要请求一个真实接口(如
/ping),确认框架已完全启动、DB 连通、配置加载完毕 - 旧进程不能立即 kill:应发送 SIGTERM,让 Hyperf 主动关闭 Worker 并等待请求结束;强制 kill -9 可能丢请求
-
静态资源和 runtime 缓存需隔离:两个实例共用
runtime/会冲突,建议按端口分目录,如runtime/9501/和runtime/9502/ - 数据库迁移需前置执行:新旧版本共存期间,SQL 必须向前兼容;DDL 变更应在切流前完成


















