Webman默认Session在集群中失效,是因为其基于Workerman常驻内存架构,各Worker进程内存隔离,且默认FileSession将数据写入本地文件,无法跨进程或跨机器共享。

Webman 本身不支持跨进程、跨机器的 Session 共享,直接调用 $request->session() 默认使用文件存储(FileSession),只适用于单机单进程调试场景。多机房或负载均衡集群下必须替换为外部统一存储,否则用户在 A 服务器登录后,请求被分发到 B 服务器时会丢失会话状态。
为什么 Webman 默认 Session 在集群中失效?
Webman 是基于 Workerman 的常驻内存框架,每个 Worker 进程拥有独立内存空间,且默认 FileSession 将数据写入本地 runtime/session/ 目录 —— 这意味着:
- 不同 Worker 进程之间无法共享同一份 Session 数据(即使同机)
- 多台服务器之间更不可能自动同步文件内容
-
session_start()和$_SESSION在 Webman 中根本不可用,强行启用会导致行为不可控
所以不能靠“复制文件”或“改 session.save_path”来解决,必须从存储层切断对本地文件的依赖。
必须用 Redis 替换 Session 存储驱动
Webman 官方提供了 RedisSession 驱动,它是目前唯一稳定、开箱即用的分布式方案。关键不是“能不能连 Redis”,而是是否正确覆盖了默认 Session 初始化逻辑。
立即学习“PHP免费学习笔记(深入)”;
实操要点:
- 确保已安装
ext-redis(非phpredis别名,也非predis包) - 在
config/session.php中将'handler'改为RedisSession::class - 配置项必须包含
'host'、'port'、'database',若需密码则加'password' - 不要手动 new
RedisSession或调用session_set_save_handler()—— Webman 的Session组件会自动接管
示例配置片段(config/session.php):
return [
'handler' => \support\session\RedisSession::class,
'options' => [
'host' => '10.0.1.100',
'port' => 6379,
'database' => 2,
'password' => 'your_pass',
'lifetime' => 7200,
],
];
注意:lifetime 是 TTL(秒),它控制 Redis 中 key 的过期时间,不是 PHP 的 session.gc_maxlifetime —— 后者在 Webman 中无效。
跨机房部署时 Redis 连接与高可用陷阱
多机房场景下,Redis 单点或主从结构容易成为瓶颈或单点故障源。但盲目上 Redis Cluster 并不推荐,因为 Webman 的 RedisSession 当前(v1.5+)仅支持单节点或哨兵(Sentinel)模式,不解析 Cluster 的 MOVED/ASK 重定向响应。
常见踩坑点:
- 配置了 Sentinel 地址却没设
'sentinel_master',导致连接失败但无明确报错 - 机房间网络延迟高(如 >50ms),
RedisSession::read()阻塞请求,拖慢首屏 - 未设置
'timeout'和'read_timeout',超时默认是 0(无限等待) - 多个机房共用一个 Redis 实例,但未做 key 前缀隔离,A 机房误删 B 机房的 session key
建议做法:
- 每个机房部署本地 Redis 哨兵集群,Webman 配置指向本机房 Sentinel(
'host'填哨兵地址列表,'sentinel_master'指定 master 名) - 在
'options'中显式加'timeout' => 0.3和'read_timeout' => 0.3 - 通过
'prefix' => 'webman:prod:shanghai:'区分机房和环境,避免 key 冲突
Cookie 跨域与 SameSite 设置经常被忽略
Session ID 本质靠客户端 Cookie(默认名 PHPSESSID)传递。多机房往往对应多域名(如 app.sh.cn、app.bj.cn),此时必须让 Cookie 可被所有子域名或目标域名识别。
关键配置在 config/session.php:
-
'domain' => '.cn'(注意开头的点)可覆盖所有二级域名 - 若需跨主域(如
a.com→b.com),必须配合后端设置Set-Cookie的SameSite=None; Secure,且 HTTPS 强制启用 - Webman 不自动加
Secure,需手动在'secure' => true,否则 Chrome 80+ 会拒绝发送 Cookie -
'httponly' => true和'samesite' => 'Lax'是安全基线,不要关
错误示范:'domain' => 'sh.cn'(缺前置点)或漏掉 'secure' => true 导致跨域登录后反复跳转登录页。



















