开了 4 个 worker 之后,用户登录后刷新页面就回到登录页,四次里只有一次正常。日志里同一个 sid 在另外三个进程中都查不到。乍看像缓存或者权限的锅,追下去往往不是。

const session = require('express-session');
const RedisStore = require('connect-redis').default;
app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
}));

追下去是这么回事:memory store 把 session 放在各自进程的堆里,cluster 按轮询分发连接,下一个请求很可能落到没有这份数据的 worker。默认的 MemoryStore 只在单进程下成立。

「cluster session 不共享」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。

先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。别只看报错的最后一行,往上看几行,真正的起因通常在上面。

具体做法是,把 session 挪到 Redis 或数据库 四个 worker 共享一份存储;不引外部存储就开 sticky 模式 按客户端 IP 粘住同一个 worker;确认 session 中间件的 store 真的换掉了 而不只是配了 secret;轮询几次接口 看同一个 sid 是否始终能取到。

验收就看一点,反复刷新十次都保持登录 redis 里能看到对应 sid 的键。

作者 9823189