BFE mod_session_sticky 模块深度解析:会话保持原理、配置与源码实现 后端网络/通信云原生【免费下载链接】bfeA modern layer 7 load balancer from baidu项目地址https://gitcode.com/gh_mirrors/bf/bfe点击查看免费下载mod_session_sticky 是 BFEBaidu Front End一款现代七层负载均衡器中负责**会话保持Session Sticky**的核心模块它确保同一用户的请求在会话有效期内始终被路由到同一个后端服务。本文以该模块的官方文档为主线结合仓库内源码bfe_modules/mod_session_sticky/与真实配置文件系统讲解 Cookie 与 Sticky 两种会话保持模式的工作原理、全部配置参数、缓存机制与源码级实现细节读者读完即可独立完成会话保持功能的配置、排障与二次理解。模块简介与适用场景mod_session_sticky 通过两种模式实现会话保持Cookie 模式将后端信息地址、端口、子集群加密后存储在 Cookie 中客户端每次请求携带该 CookieBFE 解密后据此将请求路由到对应后端Sticky 模式通过缓存机制维护 stickyid 与后端的映射关系stickyid 可从 Cookie、请求头或 URL 参数乃至 JSON 请求/响应体中获取。典型应用场景包括登录态保持、购物车会话、需要黏着到同一实例的应用如基于内存的 WebSocket 服务、以及 OpenAI 兼容接口场景下要求同一previous_response_id对应同一后端的推理服务。模块的两个核心处理阶段定义在 mod_session_sticky.go 中decodeHandler注册在HandleAfterLocation阶段请求到达时解析会话保持信息DecodeencodeHandler注册在HandleReadResponse阶段响应返回前写入会话保持信息Encode。Cookie 模式的工作原理Cookie 模式通过请求-响应两个阶段完成会话保持的建立与复用Encode编码阶段当请求首次到达且未携带会话保持信息时BFE 完成负载均衡选择出后端将后端信息序列化后加密写入 Cookie并通过Set-Cookie返回给客户端Decode解码阶段客户端后续请求携带该 CookieBFE 解密 Cookie 内容还原后端信息并据此路由。编码的源码实现在processEncode中mod_session_sticky.go后端信息被构造为SessionStickyBackend结构体后序列化加密。该结构体定义于 common.gotype SessionStickyBackend struct { Addr *string json:ip Port *int json:port SubCluster *string json:subcluster RenewTime *int64 json:renewtime }加密采用「异或掩码 Base64」的两步处理doMask与doEncodemod_session_sticky.go先用掩码逐字节异或原文再以base64.RawStdEncoding编码得到 Cookie 值。解码doDecode为逆过程。何时重设 CookieprocessEncode只在以下三种情况下重设 Cookie对应源码中needSetCookie的判断逻辑请求中没有会话保持信息sesbk nil后端发生了变化地址、端口或子集群任一不同需要续期RenewTime已到。这一设计避免了每次响应都重写 Cookie减少不必要的开销。Sticky 模式的工作原理Sticky 模式不把后端信息写入 Cookie而是维护 stickyid 与后端的映射关系Encode编码阶段BFE 选择后端后将 stickyid从 Cookie 或 JSON 响应体中获取与后端信息的映射存入缓存Decode解码阶段客户端后续请求携带相同的 stickyidBFE 从缓存中查找对应后端并路由。stickyid 的获取来源Decode 阶段 stickyid 的提取优先级为严格按此顺序命中即止Cookie Header URIParam StickyRequestField(JSON 请求体)对应源码 mod_session_sticky.go 中的依次判断逻辑。Encode 阶段 stickyid 的提取优先级为Cookie StickyResponseField(JSON 响应体)Sticky 规则要求必须配置CookieKey校验逻辑见 product_rule_load.go但 stickyid 来源可以灵活切换例如配置了Header后客户端可通过自定义请求头携带 stickyid适合无法维护 Cookie 的客户端如部分移动端 SDK、命令行工具。缓存类型本地 LRU 与 Redis 分布式缓存模块支持两种缓存类型CacheType通过统一的缓存接口getBackendFromCache/setBackendToCache屏蔽差异mod_session_sticky.go缓存类型说明适用场景local使用lru_cache.NewLRUCache存储 stickyid 与后端的映射单机部署或无需跨节点共享会话的场景redis使用 Redis 存储映射关系Redis key 前缀为bfe:stickyid:多节点部署需确保会话在不同节点间共享Redis 模式的存储细节Redis 模式通过redis_client连接 Redis连接参数在模块基础配置中指定存储时以 JSON 序列化RedisSessionDatamod_session_sticky.go包含addr、port、sub_cluster、created_at四个字段并使用Setex设置过期时间expireSeconds。由于StickyRedisKeyPrefix bfe:stickyid:实际 key 形如bfe:stickyid:stickyid多产品共用 Redis 时可通过前缀天然隔离。本地模式初始化在init中mod_session_sticky.goCacheType为local时创建 LRU 缓存容量由Basic.CacheSize决定为redis时构造redis_client.Options并创建客户端。ParseCacheType会将非法值回退为local并报错配置校验中若CacheType非local/redis则直接返回错误conf_mod_session_sticky.go。JSON 请求/响应体字段OpenAI 兼容接口的会话保持对于 OpenAI 兼容接口等场景模块支持从 JSON 请求体和响应体中提取 stickyidmod_session_sticky.goStickyRequestField从 JSON 请求体中提取 stickyid例如previous_response_id字段复用condition.ReqBodyJsonFetchStickyResponseField从 JSON 响应体中提取 stickyid例如response_id字段复用condition.HttpRespBodyJsonGet。典型流程客户端发起首次请求得到response_id后续请求携带previous_response_id引用前一次响应BFE 在 Decode 阶段从请求体提取该值、在 Encode 阶段从响应体提取新值实现整个多轮对话过程被路由到同一后端推理实例避免跨节点状态不一致。Cookie 续期机制RenewWindowCookie 的MaxAge决定其生命周期但长会话场景下用户可能因 Cookie 过期而丢失会话状态。模块通过RenewWindow续期窗口解决当 Cookie 剩余有效期小于RenewWindow时BFE 会重新设置 Cookie延长其有效期。续期时刻的计算见 mod_session_sticky.gorenew : time.Now().Unix() int64(rule.MaxAge) - int64(rule.RenewWindow)即当MaxAge - 已存活时间 RenewWindow时触发续期。若规则未显式配置RenewWindow默认取其MaxAge的一半见 product_rule_load.go。因此合理的配置策略是RenewWindow应小于MaxAge且按会话的平均活跃间隔设置保证活跃用户的会话被持续续期。掩码兼容主掩码与备用掩码Cookie 值使用掩码加密掩码长度不得小于 4MinMaskCodeLen。模块支持主掩码与备用掩码两套掩码Encode 阶段始终使用**主掩码MaskCode**加密mod_session_sticky.goDecode 阶段先用主掩码解密失败则自动尝试备用掩码StandbyMaskCodemod_session_sticky.go。该机制的价值在于更换掩码如定期轮换密钥时旧 Cookie 仍能被备用掩码解密不会中断存量会话待旧 Cookie 自然过期后可再更新备用掩码为新的主掩码实现无缝轮换。基础配置mod_session_sticky.conf模块基础配置文件为mod_session_sticky.conf其官方参数说明见 mod_session_sticky.conf.md仓库内可直接参考的真实配置位于 conf/mod_session_sticky/mod_session_sticky.conf。参数说明基础配置[Basic]配置项类型参数含义必填补充说明Basic.DataPathString规则配置文件路径是默认值为mod_session_sticky/session_sticky.data文件须存在且可读Basic.CacheSizeIntegerSticky 模式下本地缓存大小否默认值为10000仅当CacheType为local时生效。源码中若配置值小于 10000 会被重置为 10000conf_mod_session_sticky.goBasic.CacheTypeString缓存类型否默认值为local可选local本地 LRU或redisRedis 分布式缓存Log.OpenDebugBoolean是否开启模块调试日志否开启后输出decodeHandler/encodeHandler的处理前后状态与规则匹配信息Redis 配置[Redis]——仅当CacheType redis时必填配置项类型参数含义补充说明Redis.BnsStringBNS 服务名称Redis 服务发现地址Redis.ConnectTimeoutInteger连接超时时间单位毫秒必须 0Redis.ReadTimeoutInteger读取超时时间单位毫秒必须 0Redis.WriteTimeoutInteger写入超时时间单位毫秒必须 0Redis.MaxIdleInteger最大空闲连接数非负整数Redis.MaxActiveInteger最大活跃连接数0表示不限Redis.PasswordStringRedis 密码空字符串表示无密码Redis.ExpireSecondsInteger缓存过期时间单位秒必须 0Redis 相关校验逻辑见 conf_mod_session_sticky.goCacheType redis时ConnectTimeout、ReadTimeout、WriteTimeout、ExpireSeconds均须大于 0否则模块初始化失败。配置示例本地缓存模式[Basic] DataPath mod_session_sticky/session_sticky.data CacheSize 10000 CacheType local [Log] OpenDebug trueRedis 缓存模式[Basic] DataPath mod_session_sticky/session_sticky.data CacheType redis [Redis] Bns redis.service ConnectTimeout 1000 ReadTimeout 1000 WriteTimeout 1000 MaxIdle 10 MaxActive 100 Password ExpireSeconds 3600 [Log] OpenDebug true规则配置session_sticky.data规则配置文件为session_sticky.dataJSON 格式官方参数说明见 session_sticky.data.md。配置结构为「产品线 → 规则列表」每个规则包含条件与会话保持参数。参数说明配置项类型参数含义必填补充说明VersionString配置文件版本是通常采用时间戳格式如2024-01-01 00:00:00ConfigObject各产品线的规则配置是以产品线名称为键Config[k]String产品线名称是-Config[v]Array产品线规则列表是-Config[v][].CondString规则匹配条件是语法详见 condition_grammar.mdConfig[v][].TypeString会话保持类型否默认Cookie可选Cookie或StickyConfig[v][].CookieKeyStringCookie 名称否默认值为bfe_ssblSticky 模式下必填Config[v][].DomainStringCookie 的 Domain 属性否-Config[v][].PathStringCookie 的 Path 属性否若配置须以/开头Config[v][].MaxAgeIntegerCookie 的 MaxAge 属性否默认3600秒非负整数Config[v][].MaskCodeString主掩码条件Cookie 模式加密时必填长度不小于 4Config[v][].StandbyMaskCodeString备用掩码否主掩码解密失败时使用长度不小于 4Config[v][].HeaderStringSticky 模式下的 stickyid 请求头字段名否-Config[v][].URIParamStringSticky 模式下的 stickyid URL 参数名否-Config[v][].StickyRequestFieldString从 JSON 请求体提取 stickyid 的字段名如previous_response_id否用于 OpenAI 兼容接口Config[v][].StickyResponseFieldString从 JSON 响应体提取 stickyid 的字段名如response_id否用于 OpenAI 兼容接口Config[v][].SecureBooleanCookie 的 Secure 属性否默认falseConfig[v][].HttpOnlyBooleanCookie 的 HttpOnly 属性否默认falseConfig[v][].RenewWindowIntegerCookie 续期窗口否单位秒剩余有效期小于该值时重设 Cookie默认值为MaxAge的一半未配置项的默认值定义于 product_rule_load.goDefaultCookieKey bfe_ssbl、DefaultMaxAge 3600、DefaultMaskCode defaultmask、DefaultStandbyMaskCode standbymask、DefaultHttpOnly false、DefaultSecure false、MinMaskCodeLen 4。规则校验规则stickyRuleCheckproduct_rule_load.go包括必须有Cond掩码长度不小于 4CookieKey不能为空字符串MaxAge不能为负Path必须以/开头Type仅允许Cookie/StickySticky 规则必须配置CookieKey。Cookie 模式配置示例{ Version: 2024-01-01 00:00:00, Config: { example_product: [ { Cond: default_t(), Type: Cookie, CookieKey: bfe_ssbl, Domain: .example.com, Path: /, MaxAge: 3600, MaskCode: my_secret_mask_code, StandbyMaskCode: backup_mask_code, Secure: true, HttpOnly: true, RenewWindow: 1800 } ] } }Sticky 模式配置示例{ Version: 2024-01-01 00:00:00, Config: { example_product: [ { Cond: req_path_prefix_in(\/api\, true), Type: Sticky, CookieKey: JSESSIONID, Header: X-Sticky-Id, URIParam: sticky_id } ] } }规则加载与热更新规则文件通过ProductRuleConfLoad加载product_rule_load.goJSON 解码 → 整体校验 → 条件编译condition.Build→ 默认值填充最终生成ProductRuleConf并整体替换进ProductRuleTableproduct_rule_table.go表内使用读写锁保证并发安全。模块将loadConfData注册为WebHandleReload处理器mod_session_sticky.go因此支持通过 Web 管理接口热更新规则文件更新后版本号同步写入监控状态。Decode 时先按产品线查规则表未命中再查全局产品bfe_basic.GlobalProduct见decodeHandler因此可以为全局配置兜底规则、为具体产品配置差异化规则。监控项模块对外暴露的监控项如下源码中对应ModuleSessionState.Version通过 Web 监控接口获取监控项描述VERSION当前生效的规则版本号该版本号在规则加载/热更新时由m.state.Version.Set(conf.Version)写入mod_session_sticky.go可用于确认线上实际生效的规则版本与预期是否一致。源码视角一次完整的会话保持请求以 Cookie 模式为例完整调用链为请求到达decodeHandlerHandleAfterLocation按产品线查规则 →FindStickyRule匹配Cond→processDecode从CookieKey读取 Cookie依次用主/备掩码doDecode解密getStickyBackend反序列化出后端信息写入req.Context[SessionStickyBackendKey]mod_session_sticky.go负载均衡模块读取该后端信息将请求转发到对应后端响应返回时encodeHandlerHandleReadResponse执行processEncode按前文三种情况判断是否需要重设 Cookie需要时加密后端信息并Set-Cookiemod_session_sticky.go。Sticky 模式的区别仅在于Decode 从各来源提取 stickyid 后走缓存查询本地 LRU 或 RedisEncode 时将「stickyid → 后端」写入缓存而非写 Cookie。测试验证仓库提供了覆盖全面的单元测试mod_session_sticky_test.go可作为理解模块行为与排查问题的参考TestModuleSessionSticky_cookieRoundTripCookie 编解码完整往返TestModuleSessionSticky_decodeHandler_StickyHeader、StickyURIParam、StickyBodySticky 模式下从请求头、URL 参数、JSON 请求体提取 stickyidTestModuleSessionSticky_encodeHandler_StickyResponseBody从 JSON 响应体提取 stickyidTestModuleSessionSticky_encodeHandler_domainAndPathCookie 的 Domain/Path 属性设置TestModuleSessionStickyJsession、TestModuleSessionStickySecureJSESSIONID 场景与 Secure 属性TestModuleSessionSticky_getBackendFromCache本地缓存读写TestModuleSessionSticky_Init_redisInvalidBnsRedis 配置非法时的初始化失败路径。测试数据文件位于 test_data/mod_session_sticky/包含mod_session_sticky.conf、mod_session_sticky.data以及*_header.data、*_body.data、*_uriparam.data、*_jsession.data、*_secure.data等场景化规则样例可用于快速理解不同参数组合的写法。小结mod_session_sticky 以「编码/解码两阶段 本地/Redis 双缓存」的设计为 BFE 提供了灵活且高可用的会话保持能力Cookie 模式适合通用 Web 场景Sticky 模式适合无 Cookie 或需跨节点共享会话的场景JSON 字段提取则补齐了 OpenAI 兼容接口的会话黏着需求。配置上只需掌握 mod_session_sticky.conf 与 session_sticky.data 两份文件配合规则热更新与VERSION监控即可在生产环境安全落地。赞分享后端网络/通信云原生【免费下载链接】bfeA modern layer 7 load balancer from baidu项目地址https://gitcode.com/gh_mirrors/bf/bfe点击查看免费下载相关推荐AngularFire 兼容版 Firestore 集合Collection完全指南AngularFirestoreCollection 的流式 API 与实战用法AngularFire 兼容版 Firestore 集合Collection完全指南AngularFirestoreCollection 的流式 API后端网络/通信云原生BFE 会话保持Session Sticky模块配置完全指南mod_session_sticky.conf 详解BFE 会话保持Session Sticky模块配置完全指南mod_session_sticky.conf 详解 导读 本文聚焦 BFE 反向代理中 m后端网络/通信云原生Gutenberg Comments Pagination 块深度解析原理、配置与源码实现Gutenberg Comments Pagination 块深度解析原理、配置与源码实现 导读 core/comments pagination 是 Wor后端前端上一篇EdgeRemover 完整指南三步彻底卸载 Microsoft Edge支持一键装回下一篇Intel RealSense SR300 深度相机 Python 开发完整指南从 librealsense 驱动到第一帧深度数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考