Webman负载均衡需满足后端无状态、Session外置、启用健康检查三大前提,否则易现502或登出;须监听0.0.0.0、守护进程启动、超时匹配、Redis统一Session、禁用本地状态、配置与日志中心化、保障部署一致性。

Webman 做负载均衡,不能只配 Nginx upstream 就完事——后端必须无状态、Session 必须外置、健康检查必须启用,否则流量一上来就 502 或用户反复登出。
为什么 Nginx 配了 upstream 还是 502?
常见现象是 upstream prematurely closed connection 或 Connection refused,但 php start.php status 显示服务明明在跑。根本原因不是网络问题,而是 Webman 实例没按预期长期存活或监听地址不对。
- 确认所有 Webman 实例都监听
0.0.0.0:端口,而非127.0.0.1:端口;Nginx 在另一台机器上时,127.0.0.1根本不通 - 启动命令必须带
-d(守护进程模式),例如php start.php start -d;调试模式下进程随终端退出而终止 -
proxy_read_timeout要 ≥ 后端最长可能响应时间;默认 60 秒对含 Redis 查询或外部 HTTP 调用的接口极易超时 - 检查
config/server.php中的listen配置是否与 Nginxproxy_pass地址完全一致(协议、IP、端口)
Session 丢失的根本解法不是 ip_hash
加 ip_hash 看似能固定用户到某台 Webman,但 CDN、4G/5G NAT、企业出口 IP 池会让真实客户端 IP 频繁变化,导致 session key 错乱、用户被强制登出。
- 关闭所有节点的本地 session 存储:在
php.ini或运行时设置session.save_handler = redis -
session.save_path必须指向同一个 Redis 实例,例如tcp://192.168.1.20:6379?database=1 - 避免用 Memcached:它不支持原子 TTL 更新,高并发下易出现“假过期”,比 Redis 更容易丢 session
- Webman 自身不接管 session 生命周期,所以务必确保
session_start()在中间件或控制器中被显式调用(或通过session中间件自动触发)
Webman 实例必须无状态,状态要外置到共享存储
Webman 是常驻内存框架,但“常驻”不等于“有状态”。一旦你在某个实例里用 static 变量、全局数组或文件缓存用户数据,集群就会立刻不一致。
立即学习“PHP免费学习笔记(深入)”;
- 用户登录态、临时令牌、实时计数器等,全部走 Redis(推荐使用
redis.php配置的连接池) - 不要依赖
$_SERVER['REQUEST_TIME']或microtime(true)做分布式锁;改用 Redis 的SET key value EX 30 NX原子操作 - 配置中心化:把数据库地址、API 密钥、开关参数等从
config/*.php移到环境变量或 Consul/Etcd;避免某台机器改了 config 却忘了同步 - 日志统一收集:禁用各节点本地
error_log(),改用monolog+syslog或ELK,否则排查问题时得挨台查
健康检查和部署一致性是隐形瓶颈
很多故障不是架构问题,而是上线流程失控:A 服务器跑了新版本路由逻辑,B 服务器还卡在旧版中间件里,Nginx 却平均分发请求。
- Nginx
upstream必须配health_check(需 Nginx Plus)或用开源版配合自定义location /health返回 200 + JSON 状态 - 禁止手工
scp或rsync推送代码;用 Git hook 触发git archive打包 +ssh解压,确保原子发布 - 所有 Webman 实例启动前,执行
composer install --no-dev --optimize-autoloader,避免 dev 包污染生产环境 - 验证多实例一致性:写个简单脚本 curl 所有后端
/api/version,比对返回的commit hash是否一致
最容易被忽略的一点:Webman 的 start.php reload 是平滑重启,但仅限单机;跨机器部署时,没有内置的“全集群热更”机制——你得靠外部协调器(如 Ansible + 逐台 reload)或蓝绿发布来规避停机窗口。



















