mirrord 中的 NATS 队列拆分:JetStream 与核心 Pub/Sub 的完整实战指南

发布时间:2026/10/13 10:05:52

mirrord 中的 NATS 队列拆分:JetStream 与核心 Pub/Sub 的完整实战指南 开发工具云原生CLI【免费下载链接】mirrordRun any process, on your machine or in an AI agents environment, as if it were a pod in your Kubernetes cluster: real env vars, DNS, network, traffic.项目地址https://gitcode.com/gh_mirrors/mi/mirrord点击查看免费下载NATS 是 mirrord 队列拆分Queue Splitting支持的消息服务之一本文聚焦 mirrord operator 如何通过临时流 消息过滤转发把 JetStream 流消息按需路由到本地开发进程并完整覆盖从 Helm 开关、MirrordPropertyList连接配置、MirrordSplitConfig声明到 mirrord 配置文件过滤器的全部配置项。读完本文你将能独立为一个 NATS JetStream 消费型工作负载或核心 NATS pub/sub 订阅者搭建队列拆分并正确使用message_filter与jq_filter精确控制哪些消息进入你的本地环境。适用场景与前置条件队列拆分的本质是当你用 mirrord 在本地运行一个消费型应用时与部署在集群中的副本共享同一个消息源会产生竞争。NATS 队列拆分让你通过过滤器声明哪些消息归本地、哪些留给部署的应用或其他队友的本地会话。本文默认讨论JetStream应用通过**持久化拉取型消费者durable pull consumer**从流stream中读取消息核心 NATS pub/sub无 JetStream一节单独介绍普通主题订阅的拆分。NATS 服务端版本必须 ≥ 2.2因为拆分依赖消息头message headers完成路由。队列拆分是 mirrord for Teams 的企业级能力由集群内的 mirrord operator 执行。相关术语约定本文所称queue在 NATS 语境下即stream或subject。通用的队列拆分概念与全部消息过滤器参考见 Queue Splitting 总览。工作原理JetStream 拆分流程先看一个典型场景集群中有一个消费者应用通过 durable pull consumer 从某个 JetStream stream 读取消息。当第一个mirrord NATS 拆分会话启动时operator 会做以下事情创建临时主输出流main-output stream及其上的 durable consumer——两者都是原流/原消费者设置的深拷贝修补工作负载的环境变量把流名与消费者名指向临时资源operator 通过应用原始的 durable consumer读取消息并将每条消息重新发布republish到临时流名.原始主题名命中某用户过滤器的消息 → 重新发布到该会话专属的临时流本地应用从那里读取未命中任何过滤器的消息 → 重新发布到主输出流部署的工作负载从那里读取。steal 与 mirror 两种模式默认的steal模式下命中过滤器的消息只进入会话的临时流部署的应用永远看不到它。mirror模式下命中过滤器的消息同时进入会话临时流与主输出流部署的工作负载也会处理一份副本——适合需要本地观察 集群照常处理的场景。queue_mode字段在 split_queues 配置 中定义默认值为steal。投递语义at-least-once拆分保证至少一次at-least-once投递只有当 JetStream 服务端确认了 republish 之后operator 才在原始消费者上确认ack消息。因此一条消息可能被重复投递但绝不会被静默丢弃。清理与崩溃安全会话结束时其临时流被删除整个拆分结束时主输出流也被删除。清理是崩溃安全的每一个临时资源都被记录在一个MirrordClusterExternalResource中即使 operator 在会话中途重启这些资源也会被回收。从源码结构看operator 侧把每次拆分会话建模为只读的QueueSplit视图见 queue_split.rs其中的QueueSplitTmpQueue记录了临时资源的kind如stream/consumer、scopeworkload或session、原始名与临时名便于把 broker 里的临时资源追溯回所属会话QueueSplitStatus则暴露了phase、target_pods的 patched/ready 状态等实时信息。在集群中启用 NATS 拆分启用与配置共分三步Helm 开关 →MirrordPropertyList连接配置 →MirrordSplitConfig拆分声明。第一步在 Helm chart 中启用 NATS 拆分在 mirrord-operator 的 Helm values 中设置operator.natsSplitting启用JetStream 拆分本文主要步骤依赖它operator.natsPubsubSplitting启用核心 NATS pub/sub 拆分见下文专门一节。第二步创建 MirrordPropertyListoperator 需要连接你的 NATS 服务端来读取并重新发布消息。连接信息通过一个MirrordPropertyListKubernetes CustomResource定义放在目标工作负载所在的命名空间同时也是MirrordSplitConfig所在命名空间或放在operator 的命名空间以便跨命名空间共享——后者要求 operator 版本 ≥3.191.0查找顺序与覆盖规则见总览中的 Sharing Property Lists Across Namespaces。apiVersion: mirrord.metalbear.co/v1 kind: MirrordPropertyList metadata: name: nats-config namespace: events spec: properties: - name: url value: nats://nats.nats-ns.svc.cluster.local:4222支持的属性如下表属性说明必填默认urlNATS 服务端 URL例如nats://host:4222NATS 集群可用逗号分隔的 URL 列表使用tls://scheme 走 TLS 连接是tls设为true即可在不改 URL scheme 的情况下走 TLS否falseusername用户名与password配合使用否password密码与username配合使用否token认证令牌否credentialsJWT.creds文件的内容否nkeyNKey seed否ca_cert签名服务器证书的 CA bundle 的 PEM 内容适用于私有 CA隐含启用 TLS否client_cert客户端证书链的 PEM 内容用于 mTLS与client_key配合使用隐含启用 TLS否client_key客户端证书私钥的 PEM 内容与client_cert配合使用否按你的 NATS 服务端实际认证方式设置对应属性。机密信息应放在 Kubernetes Secret 中用valueFrom引用而不是明文写在 CR 里。以下是各认证方式的完整示例用户名 密码spec: properties: - name: url value: nats://nats.nats-ns.svc.cluster.local:4222 - name: username value: mirrord-operator - name: password valueFrom: secretKeyRef: name: nats-auth key: passwordToken- name: token valueFrom: secretKeyRef: name: nats-auth key: tokenJWT credentials 文件属性存放.creds文件的内容而非路径- name: credentials valueFrom: secretKeyRef: name: nats-auth key: nats.credsNKey seed- name: nkey valueFrom: secretKeyRef: name: nats-auth key: nkey.seed私有 CA 的 TLS 或双向 TLS属性都存放 PEM 内容而非路径提供任意一个都会让 operator 即使在nats://URL 上也走 TLS- name: ca_cert valueFrom: secretKeyRef: name: nats-tls key: ca.crt - name: client_cert valueFrom: secretKeyRef: name: nats-tls key: tls.crt - name: client_key valueFrom: secretKeyRef: name: nats-tls key: tls.key注意不提供ca_cert时服务器证书会按标准公共根证书验证因此仅client_certclient_key可实现针对公网可信服务器的 mTLS。第三步创建 MirrordSplitConfig启用operator.natsSplitting或operator.natsPubsubSplitting后operator 会在集群中注册新的 CRD 类型MirrordSplitConfig。可用以下命令验证其存在kubectl get crd mirrordsplitconfigs.queues.mirrord.metalbear.co为目标工作负载创建MirrordSplitConfig。NATS 的 queue 条目使用kind: natsapiVersion: queues.mirrord.metalbear.co/v1 kind: MirrordSplitConfig metadata: name: order-processor-split namespace: events spec: targetRef: apiVersion: apps/v1 kind: Deployment name: order-processor clientConfigs: nats: nats-config queues: - id: orders kind: nats appConfig: stream: - env: NATS_STREAM consumer: - env: NATS_CONSUMER以上配置的含义拆分目标是events命名空间中的 Deploymentorder-processorNATS 连接来自名为nats-config的MirrordPropertyList该 Deployment 消费一个 streamstream 名在环境变量NATS_STREAM中通过一个 durable consumer 消费消费者名在环境变量NATS_CONSUMER中该 stream 可以在 mirrord 配置中以 IDorders引用。关联到部署的消费者MirrordSplitConfig是命名空间级资源通过spec.targetRef指定目标工作负载apiVersion—— Kubernetes 工作负载的 API 版本如apps/v1kind—— 工作负载类型支持Deployment、StatefulSet、Rolloutname—— 工作负载名称。描述被消费的流spec.queues列表中的每个条目描述一个 stream 及工作负载读取它所用的 durable pull consumerid—— 任意队列 ID开发者从 mirrord 配置中引用它kind—— 必须为natsclientConfig可选—— 存放 NATS 连接的MirrordPropertyList名称也可通过spec.clientConfigs.nats为所有 NATS queue 一次性设置queueConfig可选—— 存放临时流/消费者设置的MirrordPropertyList名称见配置临时流一节appConfig.stream—— 应用如何发现 stream 名。每个条目可使用与其他队列服务相同的结构env、envLike、volume、fallback、valuePattern、containersappConfig.consumer—— 应用如何发现 durable consumer 名结构与stream相同。每个 queue 条目必须解析出恰好一个 stream 和一个 consumer。如果工作负载运行了多个消费者就为每个消费者添加一个 queue 条目。注意mirrord operator 只能读取满足以下条件之一的消费者环境变量直接定义在工作负载的 pod template 中值来自value或valueFromconfig map 引用通过envFrom从 config map 加载。配置临时流与消费者默认情况下mirrord 创建的临时流与消费者是源流/源消费者的深拷贝会继承其全部设置——包括 retention、acknowledgement wait、replication。你可以通过把queueConfig指向一个MirrordPropertyList来逐队列覆盖这些设置apiVersion: mirrord.metalbear.co/v1 kind: MirrordPropertyList metadata: name: orders-queue-config namespace: events spec: properties: - name: max_age_seconds value: 3600 - name: ack_wait_seconds value: 120 - name: num_replicas value: 1然后在MirrordSplitConfig的 queue 条目中引用它queues: - id: orders kind: nats queueConfig: orders-queue-config appConfig: stream: - env: NATS_STREAM consumer: - env: NATS_CONSUMER支持的键max_age_seconds整数秒—— 临时流保存消息的时长ack_wait_seconds整数秒—— 临时消费者在重投递前等待确认的时长。调大它可以让本地应用有更充裕的时间处理消息例如在调试时停在断点上num_replicas整数—— 临时流的副本数。每个键都可选省略的键会沿用源流/源消费者的值。某个键的值非法时会被忽略记录一条 warning 日志并回退到源值——因此一个拼写错误不会导致会话失败。设置过滤器控制哪些消息进入本地过滤器配置在 mirrord 配置文件的feature.split_queues字段中完整的过滤器参考queue_type、message_filter、jq_filter见 Queue Splitting 总览。NATS 使用queue_type: NATS。在 split_queues.rs 的QueueKind枚举中NATS与NATSPubSub是两个独立类型与SQS、Kafka、RMQ等并列配置解析会拒绝未知类型并给出明确错误。message_filter按消息头过滤message_filter把 NATS 消息头名映射到其值的正则表达式。一条消息只有所有条目都匹配才算命中且消息头名匹配区分大小写。按消息头过滤的示例——本地应用只会收到带x-tenant头且值为test的消息{ operator: true, target: deployment/order-processor/container/consumer, feature: { split_queues: { orders: { queue_type: NATS, message_filter: { x-tenant: ^test$ } } } } }jq_filter按消息体过滤jq_filter在一个包含subject、headers、payload字段的 JSON 对象上运行 jq 程序。其中payload在消息体是合法 JSON 时为解析后的对象否则为普通字符串。当 jq 程序输出true时消息匹配。按消息体过滤的示例——本地应用只会收到 JSON 体中包含user_id: test-user的消息{ operator: true, target: deployment/order-processor/container/consumer, feature: { split_queues: { orders: { queue_type: NATS, jq_filter: .payload.user_id \test-user\ } } } }从源码看CLI 会在本地用 mirrord_jaq 编译校验 jq 程序见 split_queues.rs非法程序会在会话启动前被拒绝。若同一 queue 同时设置了filter/message_filter与jq_filter则两者都必须匹配消息才算命中。会话键头Session Key Header当 operator 启用了operator.injectSessionKeyHeader设置时投递到你的会话的每一条消息都会携带一个mirrord-key头值为你的会话键session key让本地应用能区分消息属于哪个 mirrord 会话。只有投递给会话的那份副本会被盖章部署应用收到的消息永远不会被修改。NATS含核心 pub/sub通过消息头承载该键详见总览中的 Session Key Header。注意 copy-target 模式下不会注入该键。核心 NATS pub/sub无 JetStream通过普通主题订阅nc.Subscribe(...)没有 stream、没有 durable consumer消费的应用可以用独立的natsPubSubqueue kind 拆分。前提该能力要求 operator 与 Helm chart ≥3.205.0mirrord CLI ≥3.256.0。工作方式operator 订阅原始主题把每条消息重新发布到临时主题前缀之下——命中过滤器时发布到该会话的前缀否则发布到工作负载的回退前缀。应用的 subject 值被改写成前缀.原始主题因此通配符订阅orders.*、orders.无需改动即可继续工作。警告核心 NATS 不持久化任何东西因此投递是尽力而为best-effort的在拆分建立、拆除期间或 operator 短暂不可用时发布的消息不会重放。不能容忍丢消息的应用应使用 JetStream上文各节覆盖的场景。启用方式在 Helm chart 中设置operator.natsPubsubSplitting: true。operator 仍通过MirrordPropertyList连接你的 NATS 服务端——按上文创建 MirrordPropertyList的方式创建并从拆分配置的clientConfigs.nats引用与 JetStream 拆分共用同一服务器、同一套凭据。MirrordSplitConfig条目使用kind: natsPubSub和subject引用queues: - id: orders-pubsub kind: natsPubSub appConfig: subject: - env: NATS_SUBJECT在 mirrord 配置中过滤器使用queue_type: NATSPubSub与 JetStream 拆分使用相同的message_filter消息头和jq_filtersubject/headers/payload文档。由于服务端不存在临时资源——主题只是名字——会话结束时除了恢复工作负载的环境变量外没有任何资源需要清理。从源码看operator 的能力开关在 crd.rs 中分别定义为NewOperatorFeature::NatsQueueSplitting与NewOperatorFeature::NatsPubSubQueueSplitting而 CLI 在连接参数侧为两者单独跟踪 splits 与 jq filters 计数见 connect_params.rs。注意事项与限制除核心 NATS pub/sub一节外本文覆盖的都是 JetStream应用必须通过 stream 上的 durable pull consumer 消费普通主题订阅走的是尽力而为投递。NATS 服务端必须 ≥ 2.2因为拆分依赖消息头。MirrordSplitConfig中每个 queue 条目描述恰好一个 stream 和一个 consumer每个消费者对应一个条目。重新发布的消息携带主题临时流名.原始主题——原始主题被保留前面加上临时流名。拆分期间应用如果按精确主题路由会看到带前缀的主题因此应改为匹配主题后缀或使用通配符而不是完整主题。投递是 at-least-once只有 JetStream 服务端确认 republish 后原始消费者上的消息才会被 ack——你的应用可能看到同一条消息两次但绝不会漏掉。延伸阅读Queue Splitting 总览通用概念、filter/message_filter/jq_filter完整参考、跨命名空间共享属性列表、会话键头QueueSplit 状态 CRD拆分会话的实时只读视图phase、临时资源、pod 状态split_queues 配置实现QueueKind枚举、queue_mode、过滤器验证逻辑CLI 队列拆分提示mirrord 通过环境变量检测 NATS/JetStream 并提示配置拆分的实现赞分享开发工具云原生CLI【免费下载链接】mirrordRun any process, on your machine or in an AI agents environment, as if it were a pod in your Kubernetes cluster: real env vars, DNS, network, traffic.项目地址https://gitcode.com/gh_mirrors/mi/mirrord点击查看免费下载相关推荐Humanizer 完全指南用 .NET 库把字符串、枚举、日期与数量变成人类可读文本Humanizer 完全指南用 .NET 库把字符串、枚举、日期与数量变成人类可读文本 Humanizer 是一个面向 .NET 的文本人性化库专门把字符串开发工具云原生CLI如何用 mirrord 实现 SQS 队列拆分完整指南如何用 mirrord 实现 SQS 队列拆分完整指南 在现代云原生应用开发中如何优雅地处理消息队列是一个常见挑战。mirrord 提供了一个强大的 SQS开发工具云原生CLIEmulatorJS终极浏览器游戏模拟器指南 - 轻松重温30经典游戏系统EmulatorJS终极浏览器游戏模拟器指南 轻松重温30经典游戏系统 EmulatorJS 是一款功能强大的浏览器游戏模拟器让你无需安装任何软件就能在浏前端WebAssembly上一篇从零创建 Unity 强化学习环境ML-Agents RollerBall 环境构建与源码级实践指南下一篇Teleport Kubernetes 集成测试的自建镜像alpine-webserver:v1 的构建、校验与加载全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/13 10:05:52

ik_llama.cpp 中 IQ1_S_R4 量化的专属校验机制:PR 191 的实现解析

人工智能大模型推理引擎本地部署模型量化 【免费下载链接】ik_llama.cpp llama.cpp fork with additional SOTA quants and improved performance 项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp 点击查看 免费下载 本文围绕 ik_llama.cpp 仓库中…

2026/10/13 11:16:07

用联想记忆网络为量化模型注入可解释的市场记忆

我做量化研究这几年,最常被非业内朋友问的一个问题是:市场到底有没有记忆?很多教科书模型把价格当成随机游走,恨不得告诉你“过去不重要”。但在实盘里蹲久了,你一定会遇到那种“似曾相识”的走势:同样的形…

2026/10/13 11:16:07

用UTF-8彻底搞懂编码与乱码:从字节原理到项目排查实战

做技术这些年,我处理过的乱码问题少说也有几十次,从网页上突然冒出来的“锟斤拷”,到数据库里整片整片的问号,最后追根溯源,十有八九都绕不开“UTF-8”这三个字。UTF-8这套编码系统,几乎每个开发者每天都在…

2026/10/13 11:16:07

C#与OpenCvSharp移动物体识别追踪实战:检测、追踪与避坑指南

简介:这是一份基于C#与OpenCVSharp实现的移动物体识别追踪完整源码实例,适合有基础C#认知、希望入门计算机视觉或需要实际项目参考的开发者。实例覆盖背景建模、运动目标检测、轮廓提取与TrackerCSRT/KCF追踪等核心环节,并配有可直接运行的工…

2026/10/13 11:16:07

极简生活美学:打造清欢生活的五个维度

1. 生活美学的本质探索"心有清欢"这个说法最早可以追溯到苏轼《浣溪沙》中的名句"人间有味是清欢",描绘的是一种淡泊宁静的生活态度。在现代语境下,它代表着一种不追求物质堆砌、注重精神愉悦的生活方式。这种生活哲学与当下盛行的&…

2026/10/13 11:11:07

用Python挖掘利率与汇率背后的宏观风险信号

利率和汇率,是宏观金融分析里绕不开的两个变量。我刚开始做固收研究那阵子,带我的前辈提过一句:搞懂利率,你才能看懂债券市场的定价逻辑;搞懂汇率,你才能想明白资金在跨市场之间为什么这样流动。这话糙&…

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/13 0:04:41

基于Triton部署YOLO目标检测:从训练脚本到线上服务

简介:这份资源面向希望将目标检测模型落地到生产环境的深度学习开发者与算法工程师,聚焦于用 Triton Inference Server 部署 YOLOv9 的完整实战方案,解决从训练权重到线上推理服务之间的工程化难题。压缩包共 16 个文件,约 886KB&…

2026/10/13 0:04:41

手把手教你云端部署Qwen-Image-2.1:从GPU选型到在线文生图服务

Qwen-Image-2.1 这个开源的图像生成模型,最近在内容创作和 AI 应用圈子里热度相当高。它属于通义 Qwen 系列里的视觉生成分支,让我眼前一亮的是它对中文长文本的理解能力——以前用那些老方案生成带中文文字的图,十个里九个是“乱码印刷体”&…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑