默认 fiber.New() 无法跨节点共享 Session,因 memory.Store 将数据存于进程内存,多实例间不互通;必须改用 redis.NewStore 等外部存储,并统一 KeyGenerator、Cookie 配置及 Redis 连接参数。

为什么默认的 fiber.New() 无法跨节点共享 Session
Fiber 默认用 store(如 memory.NewStore())把 Session 数据存在进程内存里,每个实例独占一份。你部署多个 Fiber 实例(比如用 Nginx 做负载均衡),用户第一次请求落到 A 节点创建了 Session,第二次被分发到 B 节点——B 根本没存过这个 session.ID,sess.Get("user_id") 就返回空或 panic。
这不是配置漏了,是设计如此:内存存储天然不支持跨进程可见。
- 必须换掉默认的
memory.Store - 所有节点得连同一个外部存储后端(Redis 最常用)
- Session ID 的生成和传输方式不能依赖本地 Cookie 加密密钥不一致(见下条)
用 redis.NewStore() 替换内存存储时的关键参数
官方 github.com/gofiber/storage/redis 提供的 redis.NewStore() 是首选,但几个参数容易配错:
-
host和port必须指向同一个 Redis 实例(集群需用redis.Cluster方式初始化) -
database要显式指定(比如0),否则不同环境可能连错库 -
reset设为false(默认是true),否则每次读写都重置 TTL,导致长期活跃用户 Session 永不超时 -
expiry推荐设为24 * time.Hour,别用0(表示永不过期,Redis 内存会涨)
示例初始化片段:
使用 Playwright 为 jimeng.jianying.com 管理浏览器会话,导入 cookies/localStorage 以自动化视频生成工作流,支持图片上传等功能
store := redis.NewStore(&redis.Config{
Host: "redis.example.com",
Port: 6379,
Password: "secret",
Database: 1,
Expiry: 24 * time.Hour,
Reset: false,
})
app.Use(session.New(store))Session ID 不同步?检查 session.Config 的 KeyGenerator 和 Cookie.HTTPOnly
即使用了 Redis,如果两个节点生成的 Session ID 不一致,或 Cookie 传不过去,照样不同步。常见原因:
- 没统一
session.Config{KeyGenerator: ...},导致各节点用不同算法生成 ID(默认用uuid.NewString(),没问题;但若自定义,必须确保所有节点逻辑完全一致) -
Cookie.SameSite设成SameSiteStrictMode或SameSiteLaxMode,在跨子域或 API 调用时 Cookie 可能被浏览器丢弃 -
Cookie.Domain没设对(比如部署在api.example.com和app.example.com,应设为.example.com) -
Cookie.Secure在非 HTTPS 环境下必须为false,否则浏览器不发 Cookie
Redis 连接池和超时设置不当会导致 Session 阻塞请求
线上压测时发现部分请求卡在 sess.Save() 上?大概率是 Redis 客户端连接池或超时没调好:
- 默认
redis.NewStore()用的是go-redis/redis/v8,它的PoolSize默认是 10,高并发下容易打满——建议按 QPS × 平均耗时预估,至少设为50 - 没设
ContextTimeout(单位秒),Redis 假死时整个 HTTP 请求会卡满默认 30 秒(Go http.Server 的ReadTimeout) - 推荐加一层熔断:用
gobreaker包包装store.Get/store.Set,避免 Redis 故障拖垮整个服务
真实踩坑点:某个节点因 Redis 密码错误反复重连,连接池耗尽,后续所有 Session 操作阻塞,但日志只报 “context deadline exceeded”,得翻 Redis 客户端初始化代码才能定位。

















