裸连 nats.connect() 在生产环境总断,因其默认无重试、无健康检查、超时不可控;需显式配置重连策略、凭证安全、tls 可信证书,并启用 jetstream 与正确流配置才能保障消息可靠。

裸连 nats.Connect() 为什么在生产环境总断?
因为默认连接不重试、无健康检查、超时不可控——它只管建 TCP 连接,不管网络抖动或服务端重启。一次丢包,nc.Publish() 就静默失败,后续所有消息全卡住。
必须显式加三样东西:
-
nats.MaxReconnects(60):别设 -1,无限重连会压垮 NATS 服务端 -
nats.ReconnectWait(2 * time.Second)+nats.ReconnectJitter(100*time.Millisecond, time.Second):避免集群里所有实例同一秒重连 -
nats.UserCredentials("user.creds"):密码别塞 URL 里,nats://user:pass@localhost:4222是明文泄露风险
如果启用了 TLS,URL 必须是 tls:// 开头,且证书链要可信,否则 Connect() 会卡死不报错。
JetStream 不开,就别指望“消息不丢”
纯 NATS 是内存转发,消费者掉线期间发布的消息直接蒸发。这不是 bug,是设计。想持久化,三步缺一不可:
- 连接后立刻初始化:
js, err := jetstream.New(nc),否则第一次js.Publish()会 panic - 显式创建 Stream:
js.AddStream(...),不能靠 publish 自动触发;改配置得删流重建 - 订阅时加两个关键参数:
nats.DeliverPolicy(nats.DeliverAll)(从头消费)+nats.Durable("worker-1")(记住 offset)
RetentionPolicy 别乱选:jetstream.InterestPolicy 只存当前有订阅者关心的消息,jetstream.WorkQueuePolicy 才保证每条只投一次。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
js.Publish() 怎么防重复和乱序?
JetStream 不自动去重、不保序,得你亲手控制:
- 发消息必须带业务唯一 ID:
js.Publish("orders.created", data, nats.WithMsgID("order-789")),ID 不能是随机 UUID,得是订单号这类可追溯标识 - Stream 配置里的
Duplicates: 2*time.Minute是“去重窗口”,不是保留时间;若处理耗时超 2 分钟,重复仍会进 - 多 goroutine 并发调
js.Publish()到同一 subject,顺序不保证;关键路径建议用单 goroutine + channel 缓冲串行发布
没配 WithMsgID,就算开了 Duplicates 也白搭。
消费者不写 ACK/Nak 就等于裸奔
没幂等、没显式应答、没错误重试的消费者,在 NATS 里就是定时炸弹。一次网络抖动,可能扣两次库存。
- 处理完必须调
msg.Ack(),不调就会在AckWait超时后重投 - 失败时用
msg.NakWithDelay(10 * time.Second)+nats.MaxDeliver(3)模拟死信,别依赖“自动跳过” - 事件结构体里至少含
Type和Version字段,避免下游解析失败或路由错乱
JetStream 的 DeliverPolicy 和 Durable 名字看着像“自动续播”,其实只是记 offset——逻辑是否幂等、是否重试、是否降级,全靠你代码写实。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










