必须用 Redis 替代文件存储实现 Session 共享,否则多进程/服务器下会话丢失;需安装 phpredis、注册 RedisSessionHandler、配置 Cookie 参数,并通过 redis-cli 或 curl 验证跨进程读写一致性。

要在 Workerman 4.0.10 中实现跨进程、跨服务器的 Session 共享,必须放弃默认的文件存储方式,改用 Redis 统一托管会话数据;否则每个 Worker 进程都会写入各自独立的 session 文件,导致用户刷新页面后登录状态丢失、购物车清空、权限校验失败等典型问题。
启用 Redis 作为 Session 存储引擎
第一步:确认已安装 phpredis 扩展(非 predis),且 Redis 服务正常运行并可被 PHP 访问。若未安装,执行 sudo apt install php-redis(Ubuntu)或 pecl install redis(其他系统),然后在 php.ini 中启用 extension=redis.so。
第二步:在启动脚本顶部引入 Redis 客户端,并注册自定义 Session 处理器:
use Workerman\Protocols\Http\Session;use Workerman\Protocols\Http\Session\RedisSessionHandler;$redis = new Redis();$redis->connect('127.0.0.1', 6379);Session::setHandler(new RedisSessionHandler($redis));
这一步必须在任何 $request->session() 调用之前完成,否则仍走默认文件存储路径。注意:不要调用 session_start(),Workerman 的 Session 是按需懒加载的。
配置 Session 基础参数
设置 Session 名称、Cookie 属性与生命周期,确保客户端能稳定携带 SID:
Session::$name = 'WORKERMAN_SESS';
Session::$cookieLifetime = 7200; —— 设为 2 小时,避免长期无效会话堆积;过长易被 Redis 内存淘汰策略误删,过短则频繁重登录。
Session::$cookiePath = '/';
Session::$domain = '.yourdomain.com'; —— 若部署在子域名下(如 app.yourdomain.com),此处必须填带点号的主域名,否则 Cookie 不会被子域共享。
Session::$secure = true; —— 生产环境务必开启,强制 Cookie 只在 HTTPS 下传输;若本地开发用 HTTP,请设为 false,否则浏览器拒绝写入。
验证 Session 是否真正走 Redis
方法一:直接检查 Redis 数据
执行 redis-cli → keys "workerman_sess_*",能看到形如 workerman_sess_abc123... 的 key;再执行 get workerman_sess_abc123...,返回的是 PHP 序列化字符串,包含你存入的 username、login_time 等字段。
方法二:代码内强制触发并观察行为
在 onMessage 回调中插入以下调试逻辑:
$session = $request->session();$session->set('debug_ts', time());$connection->send("OK, saved at ". date('H:i:s'));
刷新页面多次,打开另一个终端再次执行 redis-cli get workerman_sess_...,确认 debug_ts 值随每次请求实时更新 —— 这说明不同 Worker 进程确实读写的是同一份 Redis 数据。
【关键陷阱】 如果你发现每次刷新都生成新 SID,或 Redis 中 key 数量暴涨,大概率是 Session::$name 与前端 Cookie 名不一致,或 Nginx/Apache 反向代理未透传 Cookie 请求头,需检查代理配置中是否包含 proxy_pass_request_headers on; 和 proxy_set_header Cookie $http_cookie;。
启动 Worker 并测试多进程一致性
① 在启动脚本末尾添加如下代码:
$http_worker = new Worker('http://0.0.0.0:8080');$http_worker->count = 3; —— 显式设为 3 个进程,便于观察跨进程读写效果。
② 启动服务:php start.php start -d(后台模式)或 php start.php start(前台调试)。
③ 用 curl 模拟两次请求,注意复用 Cookie:
curl -v http://127.0.0.1:8080/login -H "Cookie: WORKERMAN_SESS=abc123..."curl -v http://127.0.0.1:8080/profile -H "Cookie: WORKERMAN_SESS=abc123..."
两次请求若均由不同 PID 的 Worker 处理(可通过 ps aux | grep php 查看),但都能读取到相同 Session 数据,即证明共享成功。
这一步操作起来很简单,直接把 curl 命令复制粘贴执行就行。不需要重启 Worker,修改配置后 reload 即可生效。


















