BFE mod_wasmplugin 规则配置详解:mod_wasm.data 插件调用规则与插件元信息全解析
后端网络/通信云原生【免费下载链接】bfeA modern layer 7 load balancer from baidu项目地址https://gitcode.com/gh_mirrors/bf/bfe点击查看免费下载导读mod_wasm.data是 BFE 开源七层负载均衡器中mod_wasmplugin模块的规则配置文件它以 JSON 格式描述 wasm 插件在什么条件下被调用、调用哪些插件以及每个插件实例的运行参数。本文围绕该文件逐字段展开先讲清规则层BeforeLocationRules / ProductRules与插件层PluginMap的完整配置语义再说明插件文件的存放布局与 md5 校验要求最后结合bfe_modules/mod_wasmplugin/下的源码剖析配置加载、热更新与请求处理链路帮助你完整掌握在 BFE 中落地 wasm 插件扩展的配置方法。一、文件定位mod_wasmplugin 的两级配置体系mod_wasmplugin模块的配置由两个文件组成分工明确文件作用mod_wasm.conf基础配置INI 格式指定规则数据文件路径Basic.DataPath与插件文件目录Basic.WasmPluginPath以及是否开启 debug 日志Log.OpenDebugmod_wasm.data规则配置JSON 格式本文主角配置 wasm 插件的调用规则及插件元信息基础配置决定了mod_wasm.data的读取位置。仓库自带的示例 conf/mod_wasm/mod_wasm.conf 如下[basic] DataPath mod_wasm/mod_wasm.data WasmPluginPathwasm_plugin/ [log] OpenDebugtrue对应源码结构体见 bfe_modules/mod_wasmplugin/conf_mod_wasmplugin.goBasic.WasmPluginPath缺省时默认回退为mod_wasmBasic.DataPath缺省时默认回退为mod_wasm/mod_wasm.data两者均会经bfe_util.ConfPathProc相对配置根目录解析为绝对路径。也就是说如果你不额外配置模块会从配置根目录下的mod_wasm/mod_wasm.data加载规则、从mod_wasm/目录寻找插件文件。二、规则配置何时调用哪些插件mod_wasm.data的第一大类内容是规则配置完整字段说明如下沿用原文档配置表配置项类型参数含义必填补充描述合法性条件VersionString配置文件版本Y通常采用时间戳格式如20190101000000类型为 VersionBeforeLocationRulesArrayHandleBeforeLocation 回调点的 wasm 插件规则列表N--BeforeLocationRules[]Object一条 wasm 插件规则Y--BeforeLocationRules[].CondString匹配请求或连接的条件Y语法详见 Condition-BeforeLocationRules[].PluginListArray条件匹配时执行的 wasm 插件列表Y--BeforeLocationRules[].PluginList[]Stringwasm 插件名Y插件名须在PluginMap中已定义-ProductRulesObject各产品线的 wasm 插件规则列表N以产品线名称为键-ProductRules{k}String产品线名称Y--ProductRules{v}Array产品线下的 wasm 插件规则列表Y--ProductRules{v}[]Object一条 wasm 插件规则Y--ProductRules{v}[].CondString匹配请求或连接的条件Y语法详见 Condition-ProductRules{v}[].PluginListArray条件匹配时执行的 wasm 插件列表Y--ProductRules{v}[].PluginList[]Stringwasm 插件名Y插件名须在PluginMap中已定义-2.1 Version热更新的版本门闩Version以字符串标识本次规则配置的版本。从源码 bfe_modules/mod_wasmplugin/plugin_rule_load.go 可以看到updatePluginConf的第一步就是版本比对if conf.Version ! nil *conf.Version ! t.GetVersion() {只有当新配置的Version与内存中PluginTable当前版本不一致时才会真正执行插件映射重建、规则编译与旧插件清理。因此每次修改mod_wasm.data后必须同步更新Version字段否则即使通过热加载接口重载新规则也不会生效。常见做法是使用时间戳如20240101000000该约定与 配置文件版本Version公共类型 一致。2.2 BeforeLocationRules路由前执行的插件BeforeLocationRules挂在 BFE 的HandleBeforeLocation回调点上此时请求尚未完成产品线/集群定位适合执行与路由无关的通用处理如请求头改写、审计等。该列表按数组顺序逐条匹配从源码 bfe_modules/mod_wasmplugin/mod_wasmplugin.go 可见处理器遍历规则表命中第一条Cond匹配的规则后即取出其PluginList并依次执行随后把过滤器实例暂存到request.Context[mod_wasm_before_location_key]供响应阶段回调。2.3 ProductRules按产品线差异化调度ProductRules以产品线名称product为键值为该产品线下的一组规则其结构与BeforeLocationRules完全相同。它挂在HandleFoundProduct回调点上此时请求已定位到具体产品线处理器通过request.Route.Product查表见 plugin_table.go 的Search(product)方法实现不同产品线的插件策略隔离。例如可以为 A 产品线启用流量审计插件为 B 产品线启用不同的改写插件互不干扰。两个规则列表在 plugin_rule_load.go 的buildRuleList中走同一套编译流程先用condition.Build(*r.Cond)将条件字符串编译为可执行的条件对象编译失败则整体加载失败再逐个校验PluginList中的插件名是否已在PluginMap中注册未注册会直接返回unknown plugin: xxx错误。三、插件配置PluginMap 定义插件元信息mod_wasm.data的第二大类内容是插件配置PluginMap完整字段说明如下配置项类型参数含义必填补充描述合法性条件PluginMapObjectwasm 插件字典Y以插件名称为键-PluginMap{k}Stringwasm 插件名Y--PluginMap{v}Objectwasm 插件详细信息Y--PluginMap{v}.NameStringwasm 插件名Y须与PluginMap{k}一致-PluginMap{v}.WasmVersionStringwasm 插件文件版本Y用于匹配插件的 wasm 文件版本-PluginMap{v}.ConfVersionStringwasm 插件配置文件版本Y用于匹配插件的自定义配置文件版本-PluginMap{v}.InstanceNumIntegerwasm 插件运行实例数Y-须为非负整数PluginMap相当于整个规则文件的插件注册表规则中的PluginList只是按名字引用真正的插件实体wasm 字节码、配置、实例池都由这里定义。对应源码结构体为 plugin_rule_load.go 中的PluginMeta加载时会被转换为bfe_wasmplugin.WasmPluginConfig并调用bfe_wasmplugin.NewWasmPlugin构建插件实例。3.1 Name键值一致性约束Name必须与PluginMap{k}即 JSON 中的键名一致加载时以键名pn作为真正的插件名参与路径拼接与查表见buildNewPluginMap中PluginName: pn的传参。建议直接让两者同名避免混淆。3.2 WasmVersion 与 ConfVersion插件热更新的双版本锚点这两个字段分别标识wasm 二进制版本与插件自定义配置文件PlugName.conf版本。它们的核心价值体现在热更新时对“插件是否变化”的判断plugin_rule_load.goconfigOld : plugOld.GetConfig() if configOld.WasmVersion p.WasmVersion configOld.ConfigVersion p.ConfVersion { // not change, just copy to new map pmNew[pn] plugOld当新旧配置的WasmVersion与ConfVersion都未变化时模块直接复用内存中的旧插件实例只按需扩容实例数避免无意义的插件重建只要任一版本号变化就会重新读取插件文件、校验 md5 并重建实例池。这为插件代码与配置的独立灰度发布提供了版本锚点。3.3 InstanceNum并发能力与扩容语义InstanceNum表示该插件常驻的运行实例数须为非负整数。源码 bfe_wasmplugin/plugin.go 中有一个值得注意的默认行为instanceNum : wasmConfig.InstanceNum if instanceNum 0 { instanceNum runtime.NumCPU() }即配置为 0 或负数时会回退为当前机器 CPU 核数。实例池由EnsureInstanceNum动态伸缩扩容时逐实例注册 ABI、调用ProxyOnContextCreate/ProxyOnVmStart/ProxyOnConfigure启动缩容时Stop被裁掉的实例。请求处理时通过GetInstance()以轮询方式从实例池中取一个可用实例Acquire成功才占用用完由ReleaseInstance归还——实例数越大可同时承载的并发请求越多但内存占用也越高需要按业务峰值权衡。四、wasm 插件文件布局三件套与 md5 校验PluginMap只声明插件“叫什么、什么版本、几个实例”插件的实体文件需要预先就位。对于名为PlugName的插件其文件必须存放于WasmPluginPath/PlugName/目录下WasmPluginPath即基础配置中的Basic.WasmPluginPath文件名描述PlugName.wasmwasm 文件插件二进制字节码PlugName.md5PlugName.wasm 的 md5 文件内容为该 wasm 文件的 md5 摘要PlugName.conf插件自定义配置文件字节内容会通过ProxyOnConfigure传给插件以仓库示例 conf/mod_wasm/mod_wasm.data 中的headers插件为例文件应放在wasm_plugin/headers/下包含headers.wasm、headers.md5、headers.conf三个文件。这三件套的加载逻辑集中在 bfe_wasmplugin/plugin.go 的loadWasmBytes依次读取.wasm、.conf、.md5三个文件任一缺失或为空都会返回对应的ErrWasmBytesLoad/ErrConfigFileLoad/ErrMd5FileLoad错误读取.md5文件内容后取第一个空白分隔字段作为期望摘要再对.wasm文件内容实际计算md5.Sum两者不一致时返回ErrWasmBytesIncorrectincorrect hash of wasm bytes拒绝加载被篡改或损坏的插件文件。因此在更换插件二进制时务必同步更新对应的.md5文件否则热更新会直接失败。五、完整配置示例一个可直接落地的 JSON原文档给出的完整示例也是仓库 conf/mod_wasm/mod_wasm.data 的结构原型{ Version: 20240101000000, BeforeLocationRules: [{ Cond: req_path_prefix_in(\/headers\, false), PluginList: [ headers ] }], ProductRules: { local_product: [{ Cond: default_t(), PluginList: [] }] }, PluginMap: { headers: { Name: headers, WasmVersion: 20240101000000, ConfVersion: 20240101000000, InstanceNum: 20 } } }逐段解读BeforeLocationRules当请求路径以/headers为前缀不区分大小写case_insensitivefalse时在路由定位前执行名为headers的 wasm 插件。req_path_prefix_in是 BFE 内置条件原语参数含义与示例详见 条件原语说明。ProductRules为产品线local_product配置了一条默认规则default_t()恒真条件对应 bfe_basic/condition/build.go 中的DefaultTrueCondPluginList为空数组表示命中后不执行任何插件等价于为产品线兜底放行。default_t()与空PluginList的组合常用于占位规则避免查表不到规则时报错。PluginMap注册headers插件Name与键名一致WasmVersion/ConfVersion均设为20240101000000常驻20个运行实例。其中Cond字段使用的是 BFE 的 条件表达式语法支持req_host_in(...)、req_method_in(...)等内置原语以及、||、!、括号组合可按需写出复杂的匹配逻辑不限于示例中的单原语形式。六、源码视角加载与热更新链路理解mod_wasm.data的完整生命周期有助于排查改了配置不生效类问题。核心链路如下模块初始化ModuleWasm.Init加载基础配置后立即调用loadConfData(nil)完成首次规则加载并在HandleBeforeLocation、HandleFoundProduct、HandleReadResponse三个回调点注册过滤器见 mod_wasmplugin.go。文件解析pluginConfLoad使用 BFE 的 json 解码器读取mod_wasm.data映射为PluginConfFile结构plugin_rule_load.go。插件重建updatePluginConf先比对Version随后buildNewPluginMap依据WasmVersion/ConfVersion决定复用还是重建插件再buildRuleList编译条件与校验插件名最后PluginTable.Update原子替换整张配置表plugin_table.go 使用读写锁保护。旧插件清理cleanPlugins对未变化的插件按需收缩实例数对已删除或版本变化的插件调用OnPluginDestroy与Clear将实例数归零。热更新模块通过 web 监控框架注册了loadConfData重载处理器web_monitor.WebHandleReload运维可借助 BFE 的 web 监控端口对该模块触发配置重载重载时若Version未变整个更新会被跳过。请求处理时规则以先BeforeLocationRules、后ProductRules的顺序依次在对应回调点执行所有命中的插件过滤器统一存入请求上下文待HandleReadResponse阶段按逆序调用各过滤器的ResponseHandler并OnDestroy释放见 mod_wasmplugin.go形成完整的请求/响应双向处理闭环。仓库测试 plugin_rule_load_test.go 使用stubWasmPlugin假插件验证了规则加载、版本变化、插件复用等路径无需真实 wasm 运行时即可覆盖配置逻辑可作为理解字段行为的参考。七、配置自检清单结合文档与源码落地mod_wasm.data时建议依次确认Version每次变更后递增或改为新时间戳否则热更新不会触发PluginList中引用的每个插件名都在PluginMap中注册且Name与键名一致PluginMap中每个插件都在WasmPluginPath/插件名/下备齐.wasm、.md5、.conf三件套且.md5与.wasm内容严格匹配InstanceNum按并发预期设置0 或负数会被回退为 CPU 核数Cond语法符合 条件表达式规范可在加载日志中确认无编译错误基础配置 mod_wasm.conf 中DataPath、WasmPluginPath指向正确且目录可读。完成以上检查后即可通过 BFE 的配置热加载机制安全地发布、灰度或回退 wasm 插件能力。赞分享后端网络/通信云原生【免费下载链接】bfeA modern layer 7 load balancer from baidu项目地址https://gitcode.com/gh_mirrors/bf/bfe点击查看免费下载相关推荐BFE mod_wasmplugin 的 wasm.data 规则配置完全指南Wasm 插件规则与元数据详解BFE mod_wasmplugin 的 wasm.data 规则配置完全指南Wasm 插件规则与元数据详解 导读 mod_wasm.data 是 BFEB后端网络/通信云原生BFE mod_wasmplugin 基础配置指南mod_wasm.conf 详解与插件加载原理BFE mod_wasmplugin 基础配置指南mod_wasm.conf 详解与插件加载原理 mod_wasm.conf 是 BFE 的 mod_wasm后端网络/通信云原生BFE mod_auth_basic 规则配置指南auth_basic_rule.data 详解BFE mod_auth_basic 规则配置指南auth_basic_rule.data 详解 导读 auth_basic_rule.data 是 BFE后端网络/通信云原生上一篇react-error-boundary源码中的hasArrayChanged函数解析下一篇使用 Unity BDD 宏编写 Given/When/Then 风格的 C 语言行为驱动测试创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考