一、NATS快速入门

1,989 阅读10分钟

一,Nats介绍

1.1 核心定位与设计理念

NATS 是一个开源、高性能、轻量级的分布式消息系统。它的核心设计哲学围绕着几个关键原则:

  1. 极致的简单性: API 和协议设计都非常简洁明了,易于理解和使用。这使得开发、部署和维护的成本较低。
  2. 极致的高性能: 核心 NATS (通常称为 "Core NATS" 或 "NATS Server") 被设计为极其快速和低延迟,尤其是在发布/订阅场景下。它通常能达到每秒处理数百万条消息的吞吐量。
  3. 极致的轻量级: NATS Server 本身非常小巧(单个二进制文件,内存占用少),并且其客户端库也非常轻量,对资源消耗要求低。
  4. 云原生: NATS 天生就是为现代分布式系统和云环境设计的,支持弹性伸缩、高可用性,非常适合容器化和微服务架构。
  5. 基于主题的发布/订阅: 这是 NATS 最核心和最强大的通信模式。
  6. "At Most Once" 交付 (核心模式): 默认情况下,核心 NATS 提供尽力而为的交付保证。这意味着消息要么被成功传递一次,要么在失败时丢失(不重试)。这种设计是其实现高性能和低延迟的关键。
  7. 无持久化 (核心模式): 核心 NATS 默认不将消息持久化到磁盘。消息在内存中传递,如果服务器重启或客户端断开,未处理的消息会丢失。

1.2 核心架构组件与概念

  1. NATS Server: 消息传递的核心枢纽。负责接收、路由和分发消息。可以以单机模式运行,但更常见的是组成集群模式以实现高可用性和水平扩展。
  2. NATS Client: 连接到 NATS Server 的应用程序。使用各种编程语言(如 Go, Java, JavaScript/Typescript, Python, Ruby, C#, C, Rust 等)的官方或社区维护的客户端库。
  3. Subject: 消息传递的核心抽象。它是一个由点分隔的字符串,用于标识消息的目的地或主题。
    • 例子: orders.new, sensors.temperature.room1, user.profile.updated
    • 通配符: NATS 提供了强大的主题通配符机制,使得订阅者可以灵活地订阅感兴趣的消息集合。
      • * (单级通配符):匹配一个层级的任意部分。例如:orders.* 匹配 orders.neworders.cancel,但不匹配 orders.digital.new
      • > (多级通配符):匹配零个或多个层级的任意部分。例如:sensors.> 匹配 sensors.temperature, sensors.temperature.room1, sensors.humidity 等,多级通配符只能在最后一级使用。
  4. 消息: 在 NATS 中传递的数据单元。包含:
    • Subject: 标识消息应被路由到哪里。
    • Payload (可选): 要传输的实际数据(通常是字节数组,可以是 JSON, Protobuf, 文本等任何格式)。
    • Reply Subject (可选): 用于请求/回复模式。
    • Headers (可选): 键值对形式的元数据(较新的特性)。
  5. 发布者: 创建消息并将其发送到特定主题的客户端。它不需要知道谁(如果有的话)会接收这些消息。
  6. 订阅者: 对一个或多个主题(可以使用通配符)表达兴趣的客户端。它会接收发布到这些主题上的消息。一个主题可以有多个订阅者(广播),也可以没有订阅者(消息被丢弃)。
  7. 队列组: 一种负载均衡机制。
    • 多个订阅者使用相同的队列组名称订阅同一个主题
    • 当消息发布到该主题时,NATS Server 会随机选择队列组中的一个订阅者来接收该消息。
    • 这允许你将工作负载分布到多个消费者实例上,实现水平扩展和处理能力提升。

1.3 核心通信模式

  1. 发布/订阅: 最基本和核心的模式。

    • 发布者将消息发送到一个主题。
    • 所有订阅了该主题(或匹配通配符模式)的订阅者都会收到该消息的副本。
    • 特点:一对多广播。

    image-20250626135626233.png

  2. 请求/回复: 基于发布/订阅构建的常用模式。

    • 请求者发布一条消息到一个主题(通常是服务名称),并在消息中包含一个 Reply-to 主题(通常是临时生成的唯一主题)。
    • 响应者订阅请求主题。当收到请求消息时,处理请求,并将响应发布到请求消息中指定的 Reply-to 主题。
    • 请求者订阅它自己的 Reply-to 主题以接收响应。
    • 特点:类似 RPC,实现同步或异步交互。

    image-20250626135400894.png

  3. 队列订阅: 创建一个队列订阅的时候,订阅者注册一个队列名称,所有有相同队列名称的订阅者组成了一个队列组,当注册的主题消息发布一个消息的时候,队列组中的仅有一个成员会接收到消息。

    image-20250626135655072.png

1.4 运行模式

  1. 单机模式: 单个 NATS Server 实例。适用于开发、测试或低负载场景。无高可用性。
  2. 集群模式: 多个 NATS Server 实例组成一个集群。
    • 提供高可用性:如果一个节点故障,客户端可以自动重连到其他节点,集群继续运行。
    • 提供横向扩展:集群可以处理比单节点更大的连接数、订阅数和消息吞吐量。
    • 集群节点之间通过 Gossip 协议 自动发现和共享路由信息。
  3. 超集群/分片: 将多个独立的 NATS 集群连接起来,形成一个更大的逻辑消息系统,用于跨地域部署或超大规模场景。通常使用 gatewayleaf node 协议实现。

1.5 关键特性和优势

  1. 卓越的性能: 极低的延迟和极高的吞吐量,尤其在核心发布/订阅模式下。
  2. 极简的协议: NATS 服务器和客户端之间的通信协议 (nats://) 是文本协议(可扩展为二进制 nats://),设计简洁高效,易于实现和调试。
  3. 无代理依赖: NATS Server 是自包含的,不需要依赖外部的数据库、ZooKeeper 或 etcd 来运行(集群协调是内置的)。
  4. 灵活的订阅模型: 强大的主题和通配符系统提供了极其灵活的消息路由能力。
  5. 内置负载均衡: 通过队列组轻松实现消费者负载均衡。
  6. 客户端自动重连和故障转移: 客户端库内置了强大的重连逻辑,在服务器故障或网络中断时能自动重连到集群中的其他可用节点。
  7. 安全性: 支持 TLS/SSL 加密通信、基于 Token 或用户名/密码的认证、NKey 认证以及更复杂的基于 JWT 和配置分发的认证授权系统。
  8. 多语言支持: 广泛的官方和社区支持的客户端库。
  9. 云原生友好: 轻量级、易于容器化、支持动态扩展,完美契合 Kubernetes 和微服务架构。

1.6 NATS 2.0 与 JetStream:解决持久化需求

虽然核心 NATS 的高性能源于其 "at most once" 和无持久化设计,但许多应用场景需要更强的消息保证(至少一次、正好一次)和持久化能力。为此,NATS 2.0 引入了 JetStream

  • JetStream 是什么? 它是内置于 NATS Server 中的持久化引擎。它不是独立的服务器,而是与核心 NATS 协同工作。
  • 解决的问题:
    • 消息持久化: 将消息存储到磁盘(或内存),防止服务器重启导致消息丢失。
    • 增强的交付语义: 支持 "At Least Once" 交付(通过确认机制确保消息被处理)和 "Exactly Once" 处理(通过消费者序列号去重)。
    • 流处理: 将消息组织成持久的。流定义了消息的存储策略(如保留策略:基于时间、消息数、大小等;存储后端:文件或内存)。
    • 消费者: 从流中拉取或推送消息的实体。支持多种消费模式:
      • 推模式: JetStream 主动将消息推送给消费者(类似核心订阅)。
      • 拉模式: 消费者主动从流中请求一批消息(批处理友好)。
      • 支持多种确认机制: Ack (成功), Nak (重试), Term (不再重试), AckNext (处理中并要求下一条) 等。
      • 支持消费者配置: 如重试策略、起始位置、过滤等。
  • 核心 NATS 与 JetStream 的关系:
    • 核心 NATS 负责高性能、低延迟的即时消息传递(发布/订阅、请求/回复)。
    • JetStream 负责需要持久化和更强保证的流式消息处理。
    • 它们共享相同的 NATS Server 基础设施、网络协议和客户端连接。客户端可以使用同一个连接同时进行核心 NATS 操作和 JetStream 操作。
    • 发布到配置了 JetStream 的主题的消息会被自动持久化到流中。

1.7 与其他消息系统的比较

  • vs RabbitMQ:
    • NATS 更轻量、性能更高(尤其在纯 pub/sub)。
    • RabbitMQ 功能更丰富(多种交换类型、死信队列、更复杂的路由规则、插件体系),但相对更重。
    • NATS 主题通配符比 RabbitMQ 的 Topic Exchange 更灵活。
    • 核心 NATS 的持久化/保证不如 RabbitMQ,但 JetStream 弥补了这一点。
  • vs Apache Kafka:
    • Kafka 是分布式流处理平台,核心是持久化、分区、有序的日志。吞吐量极高,适合大数据管道和流处理。
    • NATS (Core) 更轻量、延迟更低,更适合实时消息传递和命令控制。
    • NATS 的订阅模型比 Kafka 的 Consumer Group 更灵活(通配符订阅)。
    • Kafka 的学习曲线和运维复杂度通常高于 NATS。
    • JetStream 提供了类似 Kafka 的持久化流能力,但设计更简单,与核心 NATS 集成更紧密。
  • vs MQTT Brokers (如 Mosquitto, EMQX):
    • MQTT 是标准协议,专注于 IoT,有 QoS 级别。
    • NATS 原生协议 (nats://) 性能通常更高,功能更丰富(如请求/回复、队列组)。NATS 也支持 MQTT 协议网关。
    • NATS 的集群和高可用设计通常更易于管理和扩展。

二,安装Nats

  1. 进入Gihun仓库下载:github.com/nats-io/nat…

  2. 解压后将其放入指定目录,例如:D:\nats-server-v2.11.4-windows-amd64

  3. 配置环境变量:

    • NATSPATHD:\nats-server-v2.11.4-windows-amd64
    • Path%NATSPATH%
  4. 验证:打开cmd输入:nats-server -v

  5. 运行 NATS Server

    # 基础运行(默认端口4222)
    nats-server
    
    # 带JetStream的推荐配置
    nats-server -js
    

三,Spring环境配置Nats快速入门

  1. 引入依赖

    <dependency>
        <groupId>io.nats</groupId>
        <artifactId>jnats</artifactId>
        <version>2.16.14</version> <!-- 使用最新版本 -->
    </dependency>
    
  2. 配置NATS连接

    nats:
    	# NATS服务器地址
    	server: nats://localhost:4222
    	#生产者/消费者通用主题
    	subject: orders
    
  3. 编写配置bean

    import io.nats.client.Connection;
    import io.nats.client.Nats;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class NatsConfig {
    
        @Value("${nats.server}")
        private String natsServer;
    
        @Bean
        public Connection natsConnection() throws Exception {
            return Nats.connect(natsServer);
        }
    }
    
  4. 生产者

    @RestController
    @Slf4j
    public class ProducerController {
        @Autowired
        private Connection natsConnection;
    
        @Value("${nats.subject}")
        private String subject;
    
        @PostMapping("/send")
        public String createOrder(String msg)throws TimeoutException, InterruptedException{
            log.info("[生产者] 发送消息: " + msg);
            natsConnection.publish(subject, msg.getBytes());
            natsConnection.flush(Duration.ofSeconds(5)); // 确保消息立即发送
            return "消息已提交";
        }
    }
    
  5. 消费者

    @Service
    public class NatsConsumerService {
    
        @Autowired
        private Connection natsConnection;
        @Value("${nats.subject}")
        private String subject;
    
    
        @PostConstruct 
        public void startListening() {
            // 创建消息处理器
            MessageHandler handler = msg -> {
                String message = new String(msg.getData());
                System.out.println("[消费者] 收到消息: " + message);
                // 在此处添加业务处理逻辑
                processOrder(message);
            };
    
            // 创建Dispatcher并订阅主题
            Dispatcher dispatcher = natsConnection.createDispatcher(handler);
            dispatcher.subscribe(subject);
            System.out.println("消费者已启动,监听主题: " + subject);
        }
    
        private void processOrder(String orderMessage) {
            // 实现具体业务逻辑,例如:
            // 1. 解析订单JSON
            // 2. 验证数据
            // 3. 保存到数据库
            System.out.println("处理MSG: " + orderMessage);
        }
    }
    

四,NATS-UI

介绍:免费且开源的NATS管理图形界面,轻松通过桌面应用或网页界面管理您的NATS核心、流和存储桶。

下载地址github.com/nats-nui/nu…