ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

BFE mod_userid 模块 userid_rule.data 规则配置详解:为新增用户自动下发身份标识 Cookie

BFE mod_userid 模块 userid_rule.data 规则配置详解:为新增用户自动下发身份标识 Cookie 后端网络/通信云原生【免费下载链接】bfeA modern layer 7 load balancer from baidu项目地址https://gitcode.com/gh_mirrors/bf/bfe点击查看免费下载userid_rule.data是 BFE 七层负载均衡中mod_userid模块的规则配置文件它按产品线product定义哪些请求需要被下发用户身份 Cookie、Cookie 叫什么名字、作用域与有效期如何。本文以该配置文件为核心完整讲解其 JSON 结构与每个配置项的含义并结合仓库源码剖析规则加载、条件匹配、Cookie 生成与响应注入的完整链路以及配置校验与热加载机制帮助你在实际部署中准确编写和排障这份规则文件。mod_userid 模块定位与配置文件体系mod_userid模块的核心功能是为尚不具备用户标识 Cookie 的新用户自动生成一个用户 ID并将其写入 Cookie从而实现在不同请求之间追踪同一用户。其包注释明确写道generate user identity to trace one user in different request, this mod will auto set user id for request if user id not existed in cookie to cookie见 mod_userid.go。模块运行依赖两个配置文件文件作用mod_userid.conf模块基础配置INI 格式通过[Basic].DataPath指定规则文件路径通过[Log].OpenDebug开关调试日志userid_rule.data规则配置JSON 格式即本文主角定义各产品线下发 Cookie 的具体规则模块配置解析实现在 conf_mod_userid.go 中当DataPath未设置时默认值为mod_userid/userid_rule.data再经ConfPathProc拼接配置根目录得到最终路径。仓库自带的示例模块配置 conf/mod_userid/mod_userid.conf 内容如下[basic] DataPath mod_userid/userid_rule.data [Log] OpenDebug trueuserid_rule.data 配置项总览userid_rule.data是一个顶层为 JSON 对象的规则文件其完整字段说明如下表与原文档一致并补充取值细节配置项类型含义是否必填补充说明生效条件VersionString配置文件版本号Y通常为时间戳例如2019-12-10184356类型为 VersionConfigObject各产品线的规则集合YKey 为产品名-Config{k}String产品名Y--Config{v}Array该产品下的规则列表Y--Config{v}[]Object一条规则Y--Config{v}[].CondString条件表达式Y语法参见 Condition-Config{v}[].ParamsObjectCookie 参数Y--Config{v}[].Params.NameStringCookie 名称Y--Config{v}[].Params.DomainStringCookie 所属域名N--Config{v}[].Params.PathStringCookie 路径Y--Config{v}[].Params.MaxAgeIntegerCookie 最大存活时间N单位为秒-Config{v}[].GeneratorString用户 ID 生成器N例如default-需要说明的是Generator在文档中列为可选字段例如取值default但当前仓库的解析结构体 ProductRuleData 中仅包含Cond与ParamsName/Domain/Path/MaxAge字段并未解析Generator。从源码结构看该字段可以视为预留的扩展点JSON 中即使写出该字段也不会导致加载失败但现有版本的用户 ID 生成逻辑是固定的详见下文Cookie 生成一节。字段含义深入解读Version版本号字段用于标识配置文件的版本通常填写生成或更新该文件的时间戳如2019-12-10184356。热加载成功后BFE 会将该 Version 返回给触发方详见热加载机制一节便于确认线上实际生效的配置版本。Config 与产品名Config是 JSON 对象其 Key 为产品线名称Value 为该产品线下的规则数组。产品名与 BFE 路由模块bfe_route为请求确定的产品名相对应规则在请求阶段按产品名查表匹配。Cond条件表达式每条规则都带有一个条件表达式Cond用于描述哪些请求需要触发本规则。条件表达式由 BFE 条件原语与逻辑运算符组合而成完整语法见 condition_grammar.md全部可用的原语索引见 condition_primitive_index.md。文档示例中出现了两个典型原语req_path_prefix_in(/abc, true)请求 URI 的路径以/abc为前缀第二个参数true表示大小写不敏感default_t()恒为真默认条件通常用作某产品线的兜底规则。ParamsCookie 参数Params是 JSON 对象定义了待下发 Cookie 的四个属性Name必填Cookie 名称例如bfe_userid。同一产品线下可针对不同路径下发不同名称的 Cookie如下面示例中的bfe_userid_abcDomain可选Cookie 所属域名空字符串表示不限制跟随请求 HostPath必填Cookie 路径例如/或/abc决定 Cookie 在哪些路径下随请求回传MaxAge可选Cookie 最大存活时间单位为秒。示例中的3153600即 365 天3153600 60 × 60 × 24 × 365。完整配置示例与逐条解析以下是仓库 conf/mod_userid/userid_rule.data 中的完整示例与原文档一致展示了同一产品线下配置两条规则{ Version: 2019-12-10184356, Config: { example_product: [ { Cond: req_path_prefix_in(\/abc\, true), Params: { Name: bfe_userid_abc, Domain: , Path: /abc, MaxAge: 3153600 }, Generator: default }, { Cond: default_t(), Params: { Name: bfe_userid, Domain: , Path: /, MaxAge: 3153600 }, Generator: default } ] } }逐条解读Version2019-12-10184356时间戳式版本号Config.example_product为产品线example_product定义两条规则规则按数组顺序依次判定命中即停止见下文匹配流程规则一/abc前缀当请求路径以/abc开头时向新用户下发名为bfe_userid_abc、路径为/abc、有效期 365 天的 Cookie。Domain为空表示不限定域名。这样可将/abc业务线用户的标识 Cookie 限制在/abc路径范围内回传规则二默认兜底Cond为default_t()恒真条件即其余所有未命中规则一的请求下发全局 Cookiebfe_userid路径为/有效期同样为 365 天。由于规则一优先于规则二两条规则共同构成路径前缀命中则用专用 Cookie否则用全局 Cookie的完整覆盖。在测试数据 testdata/mod_userid/userid_rule.data 中还提供了不带Generator字段的等价写法两种写法在当前版本下行为一致。规则加载与结构校验源码级规则文件由 NewConfigFromFile 负责加载先用 JSON 解码器将文件读入ConfigDataVersionConfig map[string][]ProductRuleData再调用toConfig()完成结构校验与转换userid_conf_load.go。校验规则包括产品线非空若某产品线的规则数组为空加载直接失败并返回mod_user: product %s is nil条件表达式合法每条规则的Cond通过condition.Build()编译为可执行的条件对象若引用了不存在的原语如unknown_condition()加载失败Params 非空若某条规则缺少Params加载失败并返回mod_user: product %s Params is nilMaxAge 单位换算MaxAge以秒为单位的整数值在转换时乘以time.Second得到 Go 的time.Duration。上述每条失败分支都有对应的测试数据佐证userid_rule_bad_cond.dataCond为不存在的unknown_condition()用于验证条件编译失败userid_rule_empty_params.data规则缺少Params用于验证 Params 非空校验userid_rule_empty_product.data 与 userid_rule_rules_empty.data验证产品线/规则为空时报错userid_rule_invalid_json.data非法 JSON用于验证 JSON 解码失败路径。NewConfigFromFile的加载成功/失败行为由 userid_conf_load_test.go 中的TestNewConfigFromFile覆盖对正常文件断言产物包含 1 个产品线len(a.Products) 1对不存在的文件断言返回错误。请求匹配与全局回退机制mod_userid在请求处理阶段HandleFoundProduct回调即路由确定产品之后执行 Cookie 下发判定核心实现在 reqSetUid通过conf.FindProductRules(request.Route.Product)按当前请求的产品名取出规则列表全局回退若该产品线未配置任何规则则回退查找bfe_basic.GlobalProduct即global产品线的规则。测试数据 userid_rule_global.data 演示了这种混合配置example_product只配置/abc前缀规则global产品线配置default_t()兜底规则从而让未单独配置的产品线也能获得默认的用户 Cookie依次遍历规则跳过条件不匹配的规则对命中的规则检查请求 Cookie 中是否已存在Params.Name对应的 Cookierequest.Cookie(params.Name)若已存在则直接放行不再重复下发若不存在则生成新的用户 ID构造 Cookie 写入请求上下文结束遍历。Cookie 生成与响应注入用户 ID 生成用户 ID 由 genUid 生成func genUid() string { id : fmt.Sprintf(%d_%d, time.Now().UnixNano(), rand.Intn(131-1)) return hex.EncodeToString([]byte(id)) }即当前时间的纳秒时间戳 31 位随机数拼接后做十六进制编码兼顾了唯一性与不可预测性。生成结果作为 Cookie 的Value。Cookie 构造与请求注入在 reqSetUid 中构造bfe_http.Cookiecookie : bfe_http.Cookie{ Name: params.Name, Value: genUid(), Path: params.Path, Domain: params.Domain, Expires: time.Now().Add(params.MaxAge), MaxAge: int(params.MaxAge.Seconds()), }其中Expires为当前时间加上MaxAge的绝对过期时间MaxAge为以秒计的相对存活时间——两者共同写入最终 Cookie保证新旧浏览器均能正确识别过期时间。该 Cookie 随后被加入请求的CookieMap与HttpRequest并写入上下文UidCtxKey mod_userid.uid_cookiemod_userid.go供响应阶段取用。响应阶段注入 Set-Cookie由于 BFE 对上游请求与下游响应分别处理模块在响应阶段HandleReadResponse回调通过 rspSetUid 完成真正的 Cookie 下发从请求上下文中取出UidCtxKey对应的 Cookie若存在则将其序列化后以Set-Cookie响应头追加到响应中否则直接放行不影响上游已下发的其他 Cookie。这一请求阶段打标、响应阶段落头的设计使得模块可以在不改动后端逻辑的前提下为首次访问的用户补发身份 Cookie。行为测试佐证mod_userid_test.go 中的测试覆盖了上述关键行为TestModuleUserIDSetUID2Request验证请求阶段已存在 userid与不存在 userid两种场景下Cookie 均被正确写入且MaxAge非 0见 mod_userid_test.goTestModuleUserIDSetUID2Response验证响应阶段注入Set-Cookie时不会影响后端原有的 Cookie见 mod_userid_test.go。配置热加载机制userid_rule.data支持热加载无需重启 BFE。模块在Init时通过whs.RegisterHandler(web_monitor.WebHandleReload, m.name, m.loadConfData)注册了重载回调mod_userid.go。重载入口 loadConfData 支持通过path查询参数指定新的规则文件路径重载成功后返回文件名Version格式的确认信息如userid_rule.data2019-12-10184356运维侧可据此确认新配置已生效。配置对象在读写时通过sync.RWMutex保护mod_userid.go并发安全由于规则表加载完成后即只读FindProductRules查找无需加锁见 userid_conf_load.go。小结userid_rule.data虽是一个 JSON 规则文件但其背后串联了 BFE 从配置加载、结构校验、条件编译到按产品匹配、Cookie 生成、响应注入与热加载的完整模块机制。编写该文件时只需把握几个要点Version用时间戳标识版本、Config以产品名为 Key、每条规则由Cond条件表达式 ParamsName/Path必填Domain/MaxAge可选组成、规则按数组顺序首次命中生效并可通过global产品线提供兜底。结合仓库中的 conf/mod_userid/userid_rule.data 示例与 testdata 下的各类正反用例即可快速编写出可正确加载、稳定生效的规则配置。赞分享后端网络/通信云原生【免费下载链接】bfeA modern layer 7 load balancer from baidu项目地址https://gitcode.com/gh_mirrors/bf/bfe点击查看免费下载相关推荐BFE mod_userid 规则配置指南userid_rule.data 详解与用户标识 Cookie 下发实战BFE mod_userid 规则配置指南userid_rule.data 详解与用户标识 Cookie 下发实战 导读 userid_rule.data 是后端网络/通信云原生BFE mod_userid 模块详解为新用户自动注入用户标识 CookieBFE mod_userid 模块详解为新用户自动注入用户标识 Cookie 本文以 BFEBaidu Forwarding Engine的 mod_us后端网络/通信云原生BFE 的 mod_userid 模块基于 Cookie 的用户标识生成与追踪实战指南BFE 的 mod_userid 模块基于 Cookie 的用户标识生成与追踪实战指南 导读 mod_userid 是 BFEBaidu Front En后端网络/通信云原生上一篇Video2X 免费视频超分指南4K 放大、帧插值与命令行全流程下一篇Voxblox核心功能解析为什么它是MAV规划的理想选择创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进