You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NATS JetStream流上正确实现请求-应答模式

问题背景
  • 此前参考JetStream Walkthrough编写了Go语言NATS基础示例,对应代码版本为nats-stream-example仓库2c834d7d967f024348fbaa478eae18e9749431ba提交版本
  • 后续尝试参考Request-Reply Walkthrough编写扩展示例,目标是基于JetStream实现请求-应答能力(区别于原生无JetStream的核心NATS请求应答),对应代码为nats-stream-example仓库149243b8bd30974a592061cd9d0c3a9b7f3f30fc提交版本
  • 测试时出现异常:未启动reply子命令的情况下,仅运行request子命令就收到了内容为msg.Data={"stream":"my_stream2", "seq":112}的应答
复现步骤
  1. 启动开启JetStream功能的NATS服务:
$ nats-server -js
  1. 创建指定流与绑定主题:
$ ./nats-stream-example stream-add --stream my_stream2 --subject foo2
  1. 为目标流创建拉取消费者:
$ ./nats-stream-example consumer-add --consumer pull_consumer2 --stream my_stream2
  1. 发起请求:
$ ./nats-stream-example request --subject foo2 --count 100
异常根因

测试中收到的msg.Data={"stream":"my_stream2", "seq":112}不是应答端返回的业务响应,是JetStream服务端在消息成功持久化后返回的发布确认(PubAck)。代码未区分JetStream发布确认帧和实际业务应答,把发布确认误当成请求响应返回,才会出现在未启动reply端的情况下提前收到“应答”的问题。

正确实现方案

JetStream是NATS提供的持久化流处理能力,和核心NATS的请求-应答模式是叠加使用关系,不需要完全重写请求-应答逻辑,二者组合的正确实现规则如下:

  • 流配置规则:仅为请求发送的业务主题(比如示例中的foo2)创建JetStream流,不要将请求方动态生成的reply主题纳入流的subject匹配范围,避免应答消息被流持久化干扰正常逻辑。如果确实需要持久化应答消息,单独为reply主题创建独立流,不要和请求流混用。
  • 请求侧实现要点:
    • 每个请求生成全局唯一的临时reply主题,订阅该主题等待应答
    • 调用JetStream Publish接口向业务主题发送请求时,传入构造好的、携带reply主题的消息
    • 收到消息时先判断消息来源主题:只有从reply主题收到的消息才是业务应答,直接从Publish接口同步返回的内容是JetStream的发布确认,不属于业务应答范畴
  • 应答侧实现要点:
    • 创建绑定业务主题的JetStream消费者(拉取/推送模式均可)
    • 消费到请求消息后,从消息元数据中取出请求方指定的reply主题
    • 完成业务逻辑处理后,直接调用核心NATS的Publish接口将应答发送到该reply主题即可,不需要将应答发布到JetStream流
  • 可靠性说明:如果需要保证请求消息不丢失,仅通过JetStream持久化请求侧的业务主题即可满足需求,应答侧默认走核心NATS的点对点投递即可,不需要额外配置流。

内容的提问来源于stack exchange,提问作者hnakamur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 07:06:22