NATS常见问题
2026/1/15大约 4 分钟
NATS常见问题
连接问题
1. 连接超时
问题描述:客户端无法连接到 NATS 服务器。
可能原因:
- 服务器未启动
- 网络不通
- 端口被防火墙阻止
- 认证失败
解决方案:
# 检查服务器状态
nats server check connection
# 检查端口连通性
telnet localhost 4222
# 检查防火墙
sudo iptables -L -n | grep 4222// 增加连接超时和重试
nc, err := nats.Connect("nats://localhost:4222",
nats.Timeout(10*time.Second),
nats.MaxReconnects(10),
nats.ReconnectWait(time.Second),
nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
log.Printf("Disconnected: %v", err)
}),
)2. 认证失败
问题描述:连接时提示认证错误。
解决方案:
// 检查认证信息
nc, err := nats.Connect("nats://localhost:4222",
nats.UserInfo("user", "password"),
)
if err != nil {
if err == nats.ErrAuthorization {
log.Fatal("Authentication failed: check username/password")
}
}3. 频繁断开重连
问题描述:客户端频繁断开连接。
可能原因:
- 网络不稳定
- 服务器负载过高
- 心跳超时
解决方案:
nc, err := nats.Connect("nats://localhost:4222",
nats.PingInterval(20*time.Second),
nats.MaxPingsOutstanding(5),
nats.ReconnectBufSize(8*1024*1024), // 8MB 重连缓冲
)消息问题
4. 消息丢失
问题描述:发送的消息没有被接收。
可能原因:
- 使用 NATS Core(at-most-once)
- 订阅者不在线
- 消息被过滤
解决方案:
// 使用 JetStream 确保消息持久化
js, _ := nc.JetStream()
// 发布并等待确认
ack, err := js.Publish("subject", data)
if err != nil {
log.Printf("Publish failed: %v", err)
}
log.Printf("Published: seq=%d", ack.Sequence)5. 消息重复
问题描述:同一消息被多次处理。
可能原因:
- 消费者未正确确认
- 网络问题导致重传
- 未使用消息去重
解决方案:
// 使用消息 ID 去重
js.Publish("subject", data, nats.MsgId("unique-id"))
// 消费端幂等处理
js.Subscribe("subject", func(m *nats.Msg) {
msgID := m.Header.Get("Nats-Msg-Id")
if isProcessed(msgID) {
m.Ack()
return
}
process(m.Data)
markProcessed(msgID)
m.Ack()
})6. 消息积压
问题描述:消息处理速度跟不上生产速度。
解决方案:
// 增加消费者数量
for i := 0; i < 10; i++ {
go func() {
sub, _ := js.PullSubscribe("subject", "consumer")
for {
msgs, _ := sub.Fetch(100)
for _, m := range msgs {
process(m.Data)
m.Ack()
}
}
}()
}
// 或使用队列组
js.QueueSubscribe("subject", "workers", handler)JetStream 问题
7. Stream 创建失败
问题描述:无法创建 Stream。
可能原因:
- JetStream 未启用
- 存储空间不足
- 配置错误
解决方案:
# 检查 JetStream 状态
nats account info
# 检查存储空间
df -h /data/jetstream// 检查错误详情
_, err := js.AddStream(&nats.StreamConfig{
Name: "TEST",
Subjects: []string{"test.>"},
})
if err != nil {
if errors.Is(err, nats.ErrJetStreamNotEnabled) {
log.Fatal("JetStream is not enabled")
}
log.Printf("Error: %v", err)
}8. Consumer 消费卡住
问题描述:Consumer 不再接收消息。
可能原因:
- AckWait 超时
- MaxAckPending 达到上限
- Consumer 被删除
解决方案:
// 检查 Consumer 状态
info, _ := js.ConsumerInfo("STREAM", "consumer")
log.Printf("Pending: %d, Waiting: %d", info.NumPending, info.NumWaiting)
// 重新创建 Consumer
js.DeleteConsumer("STREAM", "consumer")
js.AddConsumer("STREAM", &nats.ConsumerConfig{
Durable: "consumer",
AckWait: 60 * time.Second,
MaxAckPending: 1000,
})9. 存储空间不足
问题描述:JetStream 存储空间耗尽。
解决方案:
# 检查存储使用
nats stream report
# 清理旧消息
nats stream purge STREAM --keep 1000
# 调整保留策略
nats stream edit STREAM --max-bytes 10GB --max-age 7d集群问题
10. 集群节点无法加入
问题描述:新节点无法加入集群。
解决方案:
# 检查路由连接
curl http://localhost:8222/routez
# 检查配置
# 确保 cluster.name 一致
# 确保 routes 配置正确cluster {
name: my-cluster
listen: 0.0.0.0:6222
routes: [
nats-route://node1:6222
nats-route://node2:6222
]
}11. 集群脑裂
问题描述:集群分裂成多个部分。
解决方案:
# 使用奇数节点(3, 5, 7)
# 配置合理的超时时间
cluster {
connect_retries: 10
# 路由超时
pool_size: 3
}性能问题
12. 慢消费者
问题描述:消费者处理速度慢,被服务器断开。
解决方案:
// 监控慢消费者
nc, _ := nats.Connect(nats.DefaultURL,
nats.ErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
if err == nats.ErrSlowConsumer {
log.Printf("Slow consumer on %s", sub.Subject)
// 增加处理能力或使用 Pull 模式
}
}),
)
// 使用 Pull 模式控制消费速度
sub, _ := js.PullSubscribe("subject", "consumer")
msgs, _ := sub.Fetch(10) // 按需拉取13. 高延迟
问题描述:消息传递延迟高。
解决方案:
// 使用本地连接
nc, _ := nats.Connect("nats://127.0.0.1:4222")
// 减少消息大小
// 使用压缩
compressed := compress(data)
nc.Publish("subject", compressed)
// 检查网络延迟
nats rtt调试技巧
启用调试日志
# 服务器配置
debug: true
trace: true
logtime: true
log_file: "/var/log/nats/nats.log"使用 CLI 调试
# 监控所有消息
nats sub ">"
# 查看 Stream 状态
nats stream info STREAM
# 查看 Consumer 状态
nats consumer info STREAM CONSUMER
# 性能测试
nats bench test --pub 1 --sub 1 --msgs 10000监控端点
# 服务器信息
curl http://localhost:8222/varz
# 连接信息
curl http://localhost:8222/connz
# JetStream 信息
curl http://localhost:8222/jsz小结
本章总结了 NATS 使用过程中的常见问题和解决方案,包括连接问题、消息问题、JetStream 问题、集群问题和性能问题。遇到问题时,首先检查日志和监控端点,然后根据错误信息定位原因。
面试题预览
常见面试题
- NATS 消息丢失的可能原因有哪些?
- 如何解决 NATS 的慢消费者问题?
- JetStream Consumer 卡住如何排查?
