Zeek 的 Broker 消息通信编程接口:`base/bif/messaging.bif` 详解 网络安全网络IDS【免费下载链接】zeekZeek is a powerful network analysis framework that is much different from the typical IDS you may know.项目地址https://gitcode.com/gh_mirrors/ze/zeek点击查看免费下载base/bif/messaging.bif是 Zeek 内置 BiFBuilt-In Function内建函数模块之一为 Zeek 脚本层提供与 Broker 对等节点peer通信的核心编程接口事件发布publish、标识符同步publish_id、主题订阅/转发subscribe / forward / unsubscribe以及日志批量冲刷flush_logs。本文以 Zeek 仓库中的 messaging.bif 参考文档 为主体骨架结合 BiF 定义源码、Broker::Manager 实现 以及 Broker 框架脚本逐一讲解每个函数的签名、语义、底层调用链与真实项目用法帮助读者在自己的 Zeek 脚本中正确实现集群/分布式消息模式。1. 文档定位这是 Zeek 的消息模式参考手册Zeek 的 Broker 通信能力分布在两个 BiF 模块中base/bif/comm.bif对应参考文档 comm.bif.zeek.rst负责对等连接peering即Broker::peer、Broker::listen、Broker::unpeer、Broker::status等建立与维护节点间连接的函数base/bif/messaging.bif本文主题负责建立连接之上的各种消息模式messaging patterns即向主题发布事件、同步标识符、订阅/转发主题、冲刷日志缓冲。本文讨论的messaging.bif.zeek.rst是 zeekygen 从src/broker/messaging.bif中提取文档注释自动生成的参考文档文档注释中的:source-code:字段如base/bif/messaging.bif.zeek 23 23直接指向 messaging.bif 定义文件 中的对应行号二者一一对应是研究实现细节的入口。该模块共导出 7 个函数按用途可分为四类函数类型签名用途底层入口src/broker/Manager.ccBroker::make_eventfunction (...) : Broker::Event构造可发布的远端事件数据Manager::MakeEventBroker::publishfunction (...) : bool向指定主题发布事件Manager::PublishEventBroker::__publish_idfunction (topic: string, id: string) : bool发布标识符值订阅方同步本地值Manager::PublishIdentifierBroker::__subscribefunction (topic_prefix: string) : bool注册对某主题前缀的兴趣Manager::DoSubscribeBroker::__forwardfunction (topic_prefix: string) : bool注册转发前缀匹配事件仅转发不触达本机Manager::ForwardBroker::__unsubscribefunction (topic_prefix: string) : bool注销订阅/转发Manager::DoUnsubscribeBroker::__flush_logsfunction () : count将挂起的日志消息批量发往对等节点Manager::FlushLogBuffers其中带双下划线前缀的 5 个函数是 BiF 层的内核实现脚本层通常不直接调用而是经由 main.zeek 中的同名包装函数Broker::flush_logs()、Broker::publish_id()、Broker::subscribe()、Broker::forward()、Broker::unsubscribe()间接使用make_event与publish因为接受变长参数本身就是直接面向脚本层的完整接口。2. 发布事件Broker::make_event与Broker::publish2.1Broker::make_event(...) : Broker::Eventfunction Broker::make_event(...) : Broker::Event参数args一个事件event后跟可用于调用该事件的参数值列表。返回值一个不透明的通信数据结构Broker::Eventrecord可用于通过Broker::publish发送远端事件。Broker::Event类型本身就在 messaging.bif 中声明type Broker::Event: record;。其内部布局由Manager::MakeEvent构建字段 0 存放事件名字段 1 存放按 Broker 数据格式序列化后的参数向量Manager.cc#L1010-L1078。从源码可以确认MakeEvent在构造时会做三类校验首参必须是事件第一个参数必须是FUNC_FLAVOR_EVENT类型否则报错attempt to convert non-event into an event type参数个数必须匹配num_args ! args.size() - 1时报bad # of arguments: got %zu, expect %zu逐个参数类型校验与事件签名逐一比对same_type不匹配时报event parameter #%zu type mismatch同时把 Zeek 值转换为 Broker 数据BrokerData::ToRecordVal以便跨节点传输。2.2Broker::publish(...) : boolfunction Broker::publish(...) : bool参数topic与事件消息关联的主题topic。参数args两种形态任选其一——形态 A直接传入Broker::make_event已构造好的Broker::Event形态 B传入事件本身及随后要传递的参数列表内部自动完成make_event转化。返回值true表示消息已发送。两种形态的判定发生在 messaging.bif 的publish_event_args当第一个参数类型是 record 且与Broker::Event同型时走形态 APublishEvent(topic, rv)否则走形态 B先MakeEvent再PublishEvent。仓库中两种形态都有真实用例形态 B事件 参数直接发布见 netcontrol 的 acld 插件Broker::publish(p$acld_config$acld_topic, acld_add_rule, p$acld_id, r, ar);形态 A先 make_event 再 publish见 netcontrol 的 broker 插件 与 openflow 的 broker 插件Broker::publish(p$broker_config$topic, Broker::make_event(broker_add_rule, p$broker_id, r)); Broker::publish(state$broker_topic, Broker::make_event(broker_flow_mod, state$_name, state$broker_dpid, match, flow_mod));2.3 底层调用链Broker::publish在 BiF 层只是薄封装真正的逻辑在Manager::PublishEventManager.cc#L771-L797若本端 endpoint 已关闭is_shutdown()或当前没有对等节点也没有 hubpeer_count 0 hub_count 0直接返回true视为空操作不发消息从Broker::Eventrecord 中取出事件名与参数转换为broker::vector时间戳取当前事件时间event_mgr.CurrentEventTime()脚本层无法篡改最终经bstate-endpoint.publish(...)交给 Broker 库投递并通过 telemetry 统计外发事件Telemetry().OnOutgoingEvent与计数num_events_outgoing_metric。publish_event_args中还包含一个实用的诊断逻辑当配置了非 Broker 的集群后端且 Broker manager 未激活时调用会发出警告Non-broker cluster backend configured and Broker manager inactive. Did you mean to use Cluster::publish() instead of Broker::publish()?messaging.bif#L65-L67提示开发者在新版集群框架下改用Cluster::publish。3. 标识符同步Broker::publish_id(topic, id)function Broker::__publish_id(topic: string, id: string) : bool参数topic与消息关联的主题。参数id要发布的标识符Zeek 脚本中的全局变量名。返回值true表示消息已发送。脚本层的包装函数是Broker::publish_idmain.zeek#L489-L492。语义为将某个标识符identifier的当前值发布到指定主题收到该消息的订阅方会更新自己本地同名标识符的值——这是 Zeek 脚本间共享状态的基础机制之一。从 Manager::PublishIdentifier 的源码实现可以看出三个前置条件标识符更新特性必须开启enable_identifier_updates否则报Not publishing ID update, feature disabled本端 endpoint 未关闭当前至少存在一个对等节点peer_count 0时直接返回true空操作。随后通过global_scope()-Find(id)在全局作用域中查找该标识符取其当前值序列化后发布。若标识符不存在则返回false。真实用例见 control 框架的 controller.zeekif ( Broker::publish_id(topic, id) ) ...4. 订阅与转发subscribe/forward/unsubscribe4.1Broker::subscribe(topic_prefix) : boolfunction Broker::__subscribe(topic_prefix: string) : bool参数topic_prefix用于匹配远端消息主题的前缀。例如空前缀匹配一切主题前缀a能匹配alice、amy但匹配不了bob。返回值true表示这是一个新的事件订阅且现已注册。语义注册对所有使用该主题前缀的 peer 事件消息的兴趣。接收方只有在订阅了对应主题前缀后才能收到发布到该主题的事件并触发本地事件处理器。脚本层包装为Broker::subscribemain.zeek#L494-L497。底层 Manager::DoSubscribe 调用bstate-subscriber.add_topic(topic_prefix, ...)第二个布尔参数取决于run_state::detail::zeek_init_done——即在zeek_init期间注册的订阅与运行期注册的订阅在 Broker 内部的通告advertise行为不同这也是官方注释强调subscriptions may not be altered immediately after calling (except during zeek_init)的原因见 main.zeek#L379-L388。4.2Broker::forward(topic_prefix) : boolfunction Broker::__forward(topic_prefix: string) : bool参数topic_prefix与subscribe相同的主题前缀匹配规则。返回值true表示一个新的转发/订阅已注册。语义注册一个只转发不消费的主题订阅——匹配的事件会被转发给下游订阅者但不会在本节点接收/转发节点触发任何事件处理器。它与Broker::subscribe的唯一区别即在于此中间节点起到消息中继/路由的作用。从 Manager::Forward 可以看到实现要点函数维护一个forwarded_prefixes列表若前缀已存在则返回false避免重复注册否则先调用Subscribe(topic_prefix)建立底层订阅再把前缀记入转发列表。对应的注销逻辑在DoUnsubscribe中会先从forwarded_prefixes移除前缀再真正取消订阅。4.3Broker::unsubscribe(topic_prefix) : boolfunction Broker::__unsubscribe(topic_prefix: string) : bool参数topic_prefix此前成功调用Broker::subscribe或Broker::forward时使用过的前缀。返回值true表示对该主题前缀的兴趣不再通告。语义撤销subscribe/forward注册的兴趣。底层 Manager::DoUnsubscribe 会同时清理转发列表并执行真正的取消订阅动作。三个函数在脚本层的包装对应关系为main.zeek#L494-L506function subscribe(topic_prefix: string): bool { return __subscribe(topic_prefix); } function forward(topic_prefix: string): bool { return __forward(topic_prefix); } function unsubscribe(topic_prefix: string): bool { return __unsubscribe(topic_prefix); }5. 日志批量冲刷Broker::flush_logs() : countfunction Broker::__flush_logs() : count返回值被冲刷出去的日志消息条数。语义把本端挂起pending的日志消息立即发送给远端对等节点。官方注释特别说明通常无需手动调用仅用于对时间敏感的测试场景——因为 Zeek 的日志转发本身是批量batch进行的。脚本层包装为Broker::flush_logs()main.zeek#L484-L487并且框架默认已经在周期性地调用它main.zeek#L420-L429 中定义了事件Broker::log_flush()在zeek_init时通过schedule Broker::log_batch_interval { Broker::log_flush() }按Broker::log_batch_interval间隔循环触发每次调用flush_logs()冲刷日志缓冲。底层 Manager::FlushLogBuffers 遍历所有log_buffers逐个按log_batch_size批量Flush到 endpoint累加条数并更新 telemetry 计数num_logs_outgoing_metric。6. 实战组合一次完整的对等 → 订阅 → 收发流程将上述接口串起来一个典型的分布式 Zeek 脚本形态如下综合 cluster broker backend 与 netcontrol 插件模式# 节点 A对等 发布 event zeek_init() { Broker::peer(10.0.0.2, 47761/tcp, 3secs); # 来自 base/bif/comm.bif Broker::subscribe(/zeek/control); # 或 Broker::forward(...) 仅做中继 } event my_remote_event(x: count) { # 订阅方收到 /zeek/control 主题下事件后此处被触发 print fmt(got remote value: %d, x); } # 发布方 Broker::publish(/zeek/control, my_remote_event, 42); # 等价形态 Broker::publish(/zeek/control, Broker::make_event(my_remote_event, 42));关键配合关系先建立 peering再谈消息messaging.bif的所有函数都依赖 comm.bif 建立的节点连接Broker::peer返回true仅表示尝试连接已受理实际连接可能稍后才建立main.zeek#L303-L321。发布方无需订阅publish只负责投递到主题是否触达由订阅方的subscribe/forward决定。publish返回true只表示消息已发送不代表对端已收到或事件已执行——Broker 是异步消息系统。事件必须全局可解析make_event要求事件在两端都以相同名称可见如Cluster::hello这类框架事件参数类型在两端必须一致否则MakeEvent阶段会报类型不匹配错误。7. 注意事项与边界订阅时机官方文档与 main.zeek 的注释都强调订阅在调用后不会立即生效zeek_init期间除外不要在运行期期望调用subscribe立刻能收到事件。双下划线函数是内部接口__subscribe、__forward、__publish_id、__unsubscribe、__flush_logs均以__开头属于 BiF 内部实现脚本层应使用 main.zeek 提供的无下划线包装函数。与集群框架的关系当使用新式Cluster::*集群框架非 Broker backend时直接调用Broker::publish会触发 messaging.bif#L65-L67 的警告提示改用Cluster::publish()同一仓库中Cluster::__publish等接口在 cluster/broker 相关脚本 中另行实现。空操作语义无对等节点、无 hub 或 endpoint 已关闭时publish/publish_id返回true但实际不发送见 Manager.cc#L771-L776编程时不要用返回值判断对端是否收到。文档与源码的对应本文全部函数签名均可对照 messaging.bif.zeek.rst 中的:zeek:id:条目与 messaging.bif 中的function ... %{ ... %}定义参考文档中的:source-code:行号如23 23、35 35即为该函数在 BiF 文件中的起止行。8. 延伸阅读messaging.bif 参考文档本文的文档主体含全部函数的完整签名条目messaging.bif 定义源码BiF 层实现与原生代码Broker::Manager 实现MakeEvent/PublishEvent/PublishIdentifier/DoSubscribe/Forward/DoUnsubscribe/FlushLogBuffers的完整逻辑Broker 框架脚本脚本层包装函数、日志周期冲刷与订阅/转发/发布接口说明Broker 集群后端脚本make_eventpublish组合的真实用法Broker 集群脚本指南Zeek 集群部署中消息模式的应用背景。赞分享网络安全网络IDS【免费下载链接】zeekZeek is a powerful network analysis framework that is much different from the typical IDS you may know.项目地址https://gitcode.com/gh_mirrors/ze/zeek点击查看免费下载相关推荐PPT Master AI PPT 生成完全实操指南文档变原生可编辑 PowerPoint免费开源PPT Master AI PPT 生成完全实操指南文档变原生可编辑 PowerPoint免费开源 交付一份 PDF 或一句主题PPT Master 还你AI 技能人工智能AI 应用Jina 内部通信协议详解DataRequest 消息模型与 gRPC 服务接口规范Jina 内部通信协议详解DataRequest 消息模型与 gRPC 服务接口规范 本指南以 docs/proto/docs.md https://link后端人工智能模型推理服务微服务FastStream项目中的Broker消息发布机制详解FastStream项目中的Broker消息发布机制详解 引言 在现代分布式系统中消息队列Message Queue已成为微服务架构的核心组件。然而传统后端消息队列微服务上一篇AssetStudio终极指南免费开源工具轻松提取Unity游戏资源下一篇5分钟解锁ComfyUI极限生产力210专业节点如何重塑AI图像工作流创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考