NATS面试题
2026/1/15大约 6 分钟
NATS面试题
基础概念
1. 什么是 NATS?它有什么特点?
答案:
NATS 是一个开源的、轻量级、高性能的云原生消息系统,使用 Go 语言开发。
主要特点:
- 极致简单:零配置启动,简洁的 API
- 超高性能:单服务器可处理数百万消息/秒,微秒级延迟
- 云原生:原生支持 Kubernetes,支持多种部署模式
- 多语言支持:Go、Java、Python、JavaScript 等
- 轻量级:内存占用小,二进制文件仅几 MB
2. NATS 支持哪些消息模式?
答案:
NATS 支持三种核心消息模式:
发布/订阅(Pub/Sub)
- 发布者发送消息到主题
- 所有订阅该主题的订阅者都会收到消息
- 一对多通信
请求/响应(Request/Reply)
- 同步的请求-响应模式
- 请求者发送请求并等待响应
- 适用于 RPC 场景
队列组(Queue Groups)
- 负载均衡模式
- 同一队列组中只有一个订阅者会收到消息
- 适用于任务分发
3. NATS Core 和 JetStream 有什么区别?
答案:
| 特性 | NATS Core | JetStream |
|---|---|---|
| 消息持久化 | 不支持 | 支持 |
| 消息保证 | At-most-once | At-least-once / Exactly-once |
| 消息重放 | 不支持 | 支持 |
| 消费者管理 | 无 | 支持 |
| 适用场景 | 实时通信 | 需要可靠性的场景 |
4. NATS 的通配符有哪些?如何使用?
答案:
NATS 支持两种通配符:
单级通配符(*)
- 匹配单个层级中的任意字符
- 可以放在任意位置
- 示例:
orders.*.new匹配orders.us.new、orders.eu.new
多级通配符(>)
- 匹配一个或多个层级
- 只能放在主题末尾
- 示例:
orders.>匹配orders.us、orders.us.new、orders.eu.shipped
JetStream
5. JetStream 的 Stream 和 Consumer 是什么关系?
答案:
- Stream 是消息的存储容器,定义了消息的存储策略和保留规则
- Consumer 定义了如何从 Stream 中消费消息
关系:
- 一个 Stream 可以有多个 Consumer
- 每个 Consumer 独立维护消费位置
- Consumer 可以是 Push 或 Pull 模式
6. Push Consumer 和 Pull Consumer 的区别?
答案:
Push Consumer:
- 服务器主动推送消息给消费者
- 需要指定 DeliverSubject
- 适合实时性要求高的场景
- 可能产生慢消费者问题
Pull Consumer:
- 消费者主动拉取消息
- 可以控制消费速度
- 适合批量处理场景
- 更容易实现背压控制
// Push Consumer
js.Subscribe("orders.*", handler, nats.Durable("push-consumer"))
// Pull Consumer
sub, _ := js.PullSubscribe("orders.*", "pull-consumer")
msgs, _ := sub.Fetch(10)7. JetStream 如何保证消息不丢失?
答案:
发布确认:发布消息后等待服务器确认
ack, err := js.Publish("subject", data)消息持久化:消息存储到磁盘
js.AddStream(&nats.StreamConfig{ Storage: nats.FileStorage, })副本机制:多副本存储
js.AddStream(&nats.StreamConfig{ Replicas: 3, })消费确认:消费者处理后确认
msg.Ack()
8. JetStream 的保留策略有哪些?
答案:
LimitsPolicy(默认)
- 根据配置的限制(消息数、大小、时间)保留消息
- 超出限制时根据 Discard 策略处理
InterestPolicy
- 只保留有活跃消费者感兴趣的消息
- 所有消费者都确认后删除消息
WorkQueuePolicy
- 工作队列模式
- 消息被任一消费者确认后删除
- 适合任务队列场景
集群与高可用
9. NATS 集群如何实现高可用?
答案:
全网格集群
- 所有节点互相连接
- 客户端可以连接任意节点
- 消息自动路由到正确的订阅者
JetStream 副本
- Stream 数据多副本存储
- Leader-Follower 模式
- Leader 故障时自动选举新 Leader
客户端自动重连
nc, _ := nats.Connect("nats://n1:4222,nats://n2:4222,nats://n3:4222", nats.MaxReconnects(-1), )
10. 超级集群(Super Cluster)是什么?
答案:
超级集群是通过 Gateway 连接多个独立集群的架构,适合跨地域部署。
特点:
- 每个集群独立运行
- Gateway 负责集群间消息路由
- 支持兴趣传播(Interest Propagation)
- 减少跨地域流量
安全
11. NATS 支持哪些认证方式?
答案:
用户名密码
- 最简单的认证方式
- 适合开发测试环境
Token
- 单一 Token 认证
- 简单但安全性较低
NKey
- 基于 Ed25519 公钥加密
- 更安全,推荐生产使用
JWT
- 最灵活的认证方式
- 支持账户隔离和细粒度权限
- 适合多租户场景
12. 如何实现 NATS 的多租户隔离?
答案:
使用账户(Account)实现多租户隔离:
accounts {
TENANT_A: {
users: [{ user: user_a, password: pass_a }]
jetstream: enabled
}
TENANT_B: {
users: [{ user: user_b, password: pass_b }]
jetstream: enabled
}
}特点:
- 每个账户有独立的主题空间
- 账户间默认隔离
- 可以通过 Export/Import 共享特定主题
性能优化
13. 如何优化 NATS 的消息吞吐量?
答案:
服务器优化
- 调整系统参数(文件描述符、TCP 缓冲区)
- 使用 SSD 存储
- 增加内存缓存
客户端优化
- 使用连接池
- 批量发布消息
- 使用异步发布
消息优化
- 压缩大消息
- 合理设计主题层级
- 使用合适的 QoS
JetStream 优化
- 合理设置副本数
- 使用分区策略
- 调整保留策略
14. 什么是慢消费者?如何解决?
答案:
慢消费者是指消费速度跟不上生产速度的消费者,会导致消息积压。
解决方案:
使用 Pull 模式
sub, _ := js.PullSubscribe("subject", "consumer") msgs, _ := sub.Fetch(100) // 按需拉取增加消费者数量
js.QueueSubscribe("subject", "workers", handler)优化处理逻辑
- 异步处理
- 批量处理
- 减少 I/O 操作
监控告警
nats.ErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) { if err == nats.ErrSlowConsumer { alert("Slow consumer detected") } })
对比与选型
15. NATS vs Kafka vs RabbitMQ,如何选择?
答案:
| 特性 | NATS | Kafka | RabbitMQ |
|---|---|---|---|
| 性能 | 极高 | 高 | 中 |
| 复杂度 | 低 | 高 | 中 |
| 持久化 | JetStream | 原生 | 原生 |
| 消息顺序 | 分区内有序 | 分区内有序 | 队列内有序 |
| 适用场景 | 微服务、IoT | 大数据、日志 | 企业集成 |
选择建议:
- 选 NATS:追求简单、高性能、云原生场景
- 选 Kafka:大数据处理、日志收集、需要强顺序保证
- 选 RabbitMQ:企业集成、复杂路由、需要多种协议支持
16. NATS 适合什么场景?不适合什么场景?
答案:
适合场景:
- 微服务间通信
- IoT 设备数据采集
- 实时数据分发
- 云原生应用
- 边缘计算
不适合场景:
- 需要复杂消息路由(如 RabbitMQ 的 Exchange)
- 需要事务消息
- 需要严格的全局消息顺序
- 需要长时间存储大量历史数据
实战问题
17. 如何实现 NATS 的消息幂等处理?
答案:
// 1. 发布时指定消息 ID
js.Publish("orders.new", data, nats.MsgId("order-123"))
// 2. 消费时检查是否已处理
js.Subscribe("orders.*", func(m *nats.Msg) {
msgID := m.Header.Get("Nats-Msg-Id")
// 检查是否已处理
if redis.Exists(msgID) {
m.Ack()
return
}
// 处理消息
processOrder(m.Data)
// 标记已处理
redis.Set(msgID, "1", 24*time.Hour)
m.Ack()
})18. 如何监控 NATS 的运行状态?
答案:
HTTP 监控端点
curl http://localhost:8222/varz # 服务器信息 curl http://localhost:8222/connz # 连接信息 curl http://localhost:8222/jsz # JetStream 信息CLI 工具
nats server report jetstream nats stream report nats consumer reportPrometheus 集成
# prometheus.yml scrape_configs: - job_name: 'nats' static_configs: - targets: ['localhost:8222']关键指标
- 消息吞吐量
- 连接数
- 消息积压
- 慢消费者数量
- 存储使用率
小结
本章汇总了 NATS 相关的常见面试题,涵盖基础概念、JetStream、集群高可用、安全、性能优化和实战问题。掌握这些知识点有助于深入理解 NATS 的设计理念和最佳实践。
