fiber默认不支持分布式session,因其ctx.session()使用内存存储,重启或扩缩容即丢失,多实例间无法共享;需用redis.store替代默认存储,并正确配置keylookup、cookie属性及redis过期机制。

为什么 Fiber 默认不支持分布式 Session
Fiber 的 ctx.Session() 默认用的是内存存储,每次重启服务或扩缩容,Session 就丢;多实例部署时,用户请求落到不同节点,session.Get("user_id") 在 A 节点设了,B 节点根本读不到。这不是 bug,是设计使然——Fiber 本身追求轻量和无状态,Session 存储交由开发者按需选型。
Fiber + Redis 实现分布式 Session 的三步落地
核心是替换默认的 session.Store,用 redis.Store 替代内存实现:
- 安装
github.com/gofiber/fiber/v2/middleware/session和github.com/go-redis/redis/v9 - 初始化 Redis 客户端后,传给
session.New()的Storage字段,不是直接 new 一个内存 store - 务必设置
CookieSameSite和CookieSecure(尤其上线 HTTPS 后),否则跨域或子域名场景下 Cookie 不携带
示例关键代码:
store := redis.New(redis.Config{
Client: rdb, // *redis.Client
Prefix: "fiber:session:",
})
sess := session.New(session.Config{
Storage: store,
CookieHTTPOnly: true,
CookieSameSite: "Lax",
})
Session ID 怎么传?别只靠 Cookie
Fiber 默认从 Cookie 读 session_id,但小程序、某些内嵌 H5 或跨域 API 场景下 Cookie 可能被拦截或禁用。这时候得手动接管 ID 传递逻辑:
- 启用
Config.KeyLookup,支持从 Header(如X-Session-ID)或 URL Query(?sid=xxx)取 ID - 注意:Header 方式需前端主动透传,且后端要配 CORS 允许该 Header
- Query 方式简单但不安全,仅限调试或内网可信链路
配置示例:
sess := session.New(session.Config{
KeyLookup: "header:X-Session-ID",
// 或 "query:sid"
})
Redis 中 Session 过期不清理?检查 Prefix 和 TTL 设置
常见现象:redis-cli keys "fiber:session:*" 扫出大量过期 key 却没自动删掉。原因通常是:
- Redis 版本低于 6.0,且未开启
notify-keyspace-events配置,导致基于 Pub/Sub 的过期事件监听失效 -
session.Config.Expires设为 0 或负数,会禁用 TTL,key 永不过期 - 多个服务共用同一
Prefix但用了不同序列化方式(比如有的用 JSON,有的用 gob),反序列化失败导致 cleanup 逻辑跳过
建议统一设 Expires: 30 * time.Minute,并确认 Redis 配置含 notify-keyspace-events Ex(仅限 Redis 6+)。
最易被忽略的一点:Fiber 的 session.Store 不做后台扫描清理,它完全依赖 Redis 自身的惰性删除 + 定期删除机制。如果你用的是云 Redis(如阿里云、腾讯云),得确认控制台里“键空间通知”是否打开,否则过期 key 会越积越多。











