跳转到内容

NATS Server — 极简云原生消息中间件

是什么

NATS Server 是 NATS 生态的消息路由核心——一个 Go 写的轻量进程,客户端通过 TCP 连上来,按 subject(主题字符串)做发布/订阅或请求-应答。CNCF 毕业项目,单二进制即可跑在笔记本、K8s 或树莓派上。

日常类比:kafka货运铁路——分区、副本、日志段,吞吐巨大但铺轨成本高。rabbitmq-server分拣中心——交换机、队列、路由键规则丰富。NATS 像对讲机频道——你说「频道 orders.new」,所有调到这个频道的终端同时听到;需要留档时开 JetStream 模式,像给对讲机加录音。

启动与发布:

Terminal window
nats-server -js # 启用 JetStream 持久化
nats pub orders.new '{"id":1,"sku":"A"}'
nats sub orders.> # > 通配符订阅 orders 下所有子主题

为什么重要

不理解 NATS,下面这些事讲不清:

  • 为什么云原生微服务常选 NATS 做服务间事件总线——部署极简、延迟低
  • 为什么「默认不持久化」反而是设计选择——core NATS 追求 fire-and-forget 速度
  • 为什么 JetStream 让 NATS 能对标 kafka 部分场景——流、消费者组、ACK
  • 为什么 40+ 语言都有客户端——协议简单,边缘设备也能集成

核心要点

  1. Subject 路由:层级命名 orders.us.east* 匹配单层,> 匹配多层尾部。订阅表在 server 内存维护。

  2. Core vs JetStream:Core 纯内存转发,最快;JetStream 把消息写入流文件,支持 at-least-once、回放、限速。

  3. 集群与超级集群:多 server 通过 gossip 交换路由,客户端连任意节点即可发现全局 subject。

  4. 安全:TLS、NKeys/JWT 账户隔离、鉴权可细到 subject 级。

  5. 轻量 observability:内建 varz/ping 便于健康检查,K8s liveness 好接。

实践案例

案例 1:微服务事件广播

Terminal window
# 服务 A 发布用户注册事件
nats pub users.registered '{"uid":"u42"}'
# 服务 B/C 各自订阅处理
nats sub users.registered

无队列堆积概念时,慢消费者要靠应用层背压或改 JetStream。

案例 2:JetStream 持久化流

Terminal window
nats stream add ORDERS --subjects "orders.>" --storage file --retention limits
nats consumer add ORDERS shipper --filter "orders.ship" --ack explicit

流落盘后可重启恢复;--ack explicit 保证处理完才确认,类似 kafka consumer offset。

案例 3:与 rabbitmq-server 对照

维度NATS CoreNATS JetStreamrabbitmq-server
持久化队列持久化
路由模型subject 通配stream + consumerexchange + queue
运维复杂度极低中高
典型延迟亚毫秒级毫秒级毫秒级

订单漏斗、日志采集倾向 Kafka;轻量通知、IoT 遥测倾向 NATS。

踩过的坑

  1. 以为默认会存消息——core NATS 重启即丢在途,要业务容忍或启用 JetStream。

  2. subject 设计过扁——全用 event 一条 subject,订阅方收到无关流量。

  3. JetStream 磁盘没规划——流无限增长撑满盘;必须设 retention 与 max bytes。

  4. 用 NATS 扛 Kafka 级吞吐——分区日志不是其核心优化方向,别硬比 MB/s。

适用 vs 不适用场景

适用

  • 服务间轻量 pub/sub、控制面事件
  • 边缘/嵌入式设备上报遥测
  • 需要极简运维的消息层

不适用

  • 海量日志归档(优先 kafka
  • 复杂路由与死信队列(rabbitmq-server 更成熟)
  • 需要 SQL 式消息查询(考虑 pulsar 等)

历史小故事(可跳过)

  • 2010:Derek Collison 在 VMware 时期开始 NATS 设计
  • 2018:捐赠给 CNCF;Synadia 公司持续商业支持
  • 2020+:JetStream 成熟,补齐持久化与流处理
  • 2024:CNCF 毕业;安全审计由 OSTIF 资助

学到什么

  1. 消息系统可以先极简再叠持久化——core + JetStream 分层很清晰
  2. subject 命名就是 API 设计——通配符规则决定扩展性
  3. 云原生不等于重——单二进制 + 集群 gossip 也能横向扩展
  4. 选型看交付语义——at-most-once / at-least-once 要比吞吐先想清楚
  5. CNCF 毕业是运维信心信号——安全审计与生态文档更完整

延伸阅读

与同类对比

方案协议风格持久化典型规模许可证
NATS自定义文本JetStream 可选中小集群Apache 2.0
kafka二进制日志大数据流Apache 2.0
redisRedisStream 可选缓存+轻队列SSPL
pulsar二进制分层存储多租户Apache 2.0
rabbitmq-serverAMQP队列企业集成MPL

部署体积上 NATS 常是最小可运行消息面之一:单二进制、默认配置即可 pub/sub,适合边缘网关先上线再叠 JetStream。

关联

  • kafka —— 日志流与高吞吐对照
  • rabbitmq-server —— AMQP 路由与队列语义
  • pulsar —— 云原生多租户消息
  • redis —— Stream 轻量队列替代
  • etcd —— 常同栈出现,协调 vs 事件分工
  • kubernetes —— 控制面事件与 sidecar 通信常见 NATS

微服务里把「配置协调」交给 etcd,把「业务事件」交给 NATS,是常见职责切分。

新手可先 nats-server -js 本地起服,用 nats pub/sub 验证 subject 再接入业务。

反向链接

  • etcd —— etcd — 分布式键值数据库
  • kubernetes —— Kubernetes — 容器编排平台
  • lmdb —— LMDB — 闪电内存映射嵌入式 KV 库
  • pulsar —— Apache Pulsar — 云原生消息队列
  • rabbitmq-server —— RabbitMQ — 用 Erlang 写的多协议消息总线
  • redis —— Redis — 内存键值数据库