一,Nats介绍
1.1 核心定位与设计理念
NATS 是一个开源、高性能、轻量级的分布式消息系统。它的核心设计哲学围绕着几个关键原则:
- 极致的简单性: API 和协议设计都非常简洁明了,易于理解和使用。这使得开发、部署和维护的成本较低。
- 极致的高性能: 核心 NATS (通常称为 "Core NATS" 或 "NATS Server") 被设计为极其快速和低延迟,尤其是在发布/订阅场景下。它通常能达到每秒处理数百万条消息的吞吐量。
- 极致的轻量级: NATS Server 本身非常小巧(单个二进制文件,内存占用少),并且其客户端库也非常轻量,对资源消耗要求低。
- 云原生: NATS 天生就是为现代分布式系统和云环境设计的,支持弹性伸缩、高可用性,非常适合容器化和微服务架构。
- 基于主题的发布/订阅: 这是 NATS 最核心和最强大的通信模式。
- "At Most Once" 交付 (核心模式): 默认情况下,核心 NATS 提供尽力而为的交付保证。这意味着消息要么被成功传递一次,要么在失败时丢失(不重试)。这种设计是其实现高性能和低延迟的关键。
- 无持久化 (核心模式): 核心 NATS 默认不将消息持久化到磁盘。消息在内存中传递,如果服务器重启或客户端断开,未处理的消息会丢失。
1.2 核心架构组件与概念
- NATS Server: 消息传递的核心枢纽。负责接收、路由和分发消息。可以以单机模式运行,但更常见的是组成集群模式以实现高可用性和水平扩展。
- NATS Client: 连接到 NATS Server 的应用程序。使用各种编程语言(如 Go, Java, JavaScript/Typescript, Python, Ruby, C#, C, Rust 等)的官方或社区维护的客户端库。
- Subject: 消息传递的核心抽象。它是一个由点分隔的字符串,用于标识消息的目的地或主题。
- 例子:
orders.new,sensors.temperature.room1,user.profile.updated - 通配符: NATS 提供了强大的主题通配符机制,使得订阅者可以灵活地订阅感兴趣的消息集合。
*(单级通配符):匹配一个层级的任意部分。例如:orders.*匹配orders.new和orders.cancel,但不匹配orders.digital.new。>(多级通配符):匹配零个或多个层级的任意部分。例如:sensors.>匹配sensors.temperature,sensors.temperature.room1,sensors.humidity等,多级通配符只能在最后一级使用。
- 例子:
- 消息: 在 NATS 中传递的数据单元。包含:
- Subject: 标识消息应被路由到哪里。
- Payload (可选): 要传输的实际数据(通常是字节数组,可以是 JSON, Protobuf, 文本等任何格式)。
- Reply Subject (可选): 用于请求/回复模式。
- Headers (可选): 键值对形式的元数据(较新的特性)。
- 发布者: 创建消息并将其发送到特定主题的客户端。它不需要知道谁(如果有的话)会接收这些消息。
- 订阅者: 对一个或多个主题(可以使用通配符)表达兴趣的客户端。它会接收发布到这些主题上的消息。一个主题可以有多个订阅者(广播),也可以没有订阅者(消息被丢弃)。
- 队列组: 一种负载均衡机制。
- 多个订阅者使用相同的队列组名称订阅同一个主题。
- 当消息发布到该主题时,NATS Server 会随机选择队列组中的一个订阅者来接收该消息。
- 这允许你将工作负载分布到多个消费者实例上,实现水平扩展和处理能力提升。
1.3 核心通信模式
-
发布/订阅: 最基本和核心的模式。
- 发布者将消息发送到一个主题。
- 所有订阅了该主题(或匹配通配符模式)的订阅者都会收到该消息的副本。
- 特点:一对多广播。
-
请求/回复: 基于发布/订阅构建的常用模式。
- 请求者发布一条消息到一个主题(通常是服务名称),并在消息中包含一个
Reply-to主题(通常是临时生成的唯一主题)。 - 响应者订阅请求主题。当收到请求消息时,处理请求,并将响应发布到请求消息中指定的
Reply-to主题。 - 请求者订阅它自己的
Reply-to主题以接收响应。 - 特点:类似 RPC,实现同步或异步交互。
- 请求者发布一条消息到一个主题(通常是服务名称),并在消息中包含一个
-
队列订阅: 创建一个队列订阅的时候,订阅者注册一个队列名称,所有有相同队列名称的订阅者组成了一个队列组,当注册的主题消息发布一个消息的时候,队列组中的仅有一个成员会接收到消息。
1.4 运行模式
- 单机模式: 单个 NATS Server 实例。适用于开发、测试或低负载场景。无高可用性。
- 集群模式: 多个 NATS Server 实例组成一个集群。
- 提供高可用性:如果一个节点故障,客户端可以自动重连到其他节点,集群继续运行。
- 提供横向扩展:集群可以处理比单节点更大的连接数、订阅数和消息吞吐量。
- 集群节点之间通过 Gossip 协议 自动发现和共享路由信息。
- 超集群/分片: 将多个独立的 NATS 集群连接起来,形成一个更大的逻辑消息系统,用于跨地域部署或超大规模场景。通常使用
gateway或leaf node协议实现。
1.5 关键特性和优势
- 卓越的性能: 极低的延迟和极高的吞吐量,尤其在核心发布/订阅模式下。
- 极简的协议: NATS 服务器和客户端之间的通信协议 (
nats://) 是文本协议(可扩展为二进制nats://),设计简洁高效,易于实现和调试。 - 无代理依赖: NATS Server 是自包含的,不需要依赖外部的数据库、ZooKeeper 或 etcd 来运行(集群协调是内置的)。
- 灵活的订阅模型: 强大的主题和通配符系统提供了极其灵活的消息路由能力。
- 内置负载均衡: 通过队列组轻松实现消费者负载均衡。
- 客户端自动重连和故障转移: 客户端库内置了强大的重连逻辑,在服务器故障或网络中断时能自动重连到集群中的其他可用节点。
- 安全性: 支持 TLS/SSL 加密通信、基于 Token 或用户名/密码的认证、NKey 认证以及更复杂的基于 JWT 和配置分发的认证授权系统。
- 多语言支持: 广泛的官方和社区支持的客户端库。
- 云原生友好: 轻量级、易于容器化、支持动态扩展,完美契合 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
-
进入Gihun仓库下载:github.com/nats-io/nat…
-
解压后将其放入指定目录,例如:
D:\nats-server-v2.11.4-windows-amd64 -
配置环境变量:
NATSPATH:D:\nats-server-v2.11.4-windows-amd64Path:%NATSPATH%
-
验证:打开cmd输入:
nats-server -v -
运行 NATS Server:
# 基础运行(默认端口4222) nats-server # 带JetStream的推荐配置 nats-server -js
三,Spring环境配置Nats快速入门
-
引入依赖
<dependency> <groupId>io.nats</groupId> <artifactId>jnats</artifactId> <version>2.16.14</version> <!-- 使用最新版本 --> </dependency> -
配置NATS连接
nats: # NATS服务器地址 server: nats://localhost:4222 #生产者/消费者通用主题 subject: orders -
编写配置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); } } -
生产者
@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 "消息已提交"; } } -
消费者
@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核心、流和存储桶。