NATS生产环境连接需显式配置TLS、凭证和重连策略,JetStream需手动初始化并校验,流与消费者为服务端资源须运维管控。

连接时没配TLS或凭证,Connect() 会卡住不报错
用 nats.Connect("nats://...") 直连生产环境,最常见的现象是程序 hang 在连接阶段,日志里既无成功也无错误。这不是超时问题,而是 TLS 握手失败或认证被拒后客户端默认静默重试 —— 它根本不会主动告诉你“证书不可信”或“用户不存在”。
- URL 必须带协议前缀:
"tls://nats.example.com:4443",不能只写域名或 IP;否则客户端可能跳过 TLS 初始化 - 服务端证书若非公网 CA 签发(如自建 CA、内网 Let's Encrypt 私有实例),必须显式提供根证书:
nats.RootCAs("/path/to/ca.pem") - 密码类认证(token / user/pass)严禁拼在 URL 里,例如
"nats://user:pass@..."—— 会被明文记录在进程参数、日志、监控中 - 推荐用凭证文件:
nats.UserCredentials("./nats.creds"),该文件由nsc工具生成,含加密密钥和签名,比 token 更安全
nats.Connect() 的重连参数不设等于放弃连接韧性
裸调 nats.Connect() 默认行为是:无限重试、无等待间隔、不 jitter、不校验健康。网络抖动一次,所有实例在同一毫秒发起重连请求,瞬间打爆服务端连接数或认证服务。
-
nats.MaxReconnects(60):别用-1,生产环境建议设有限值(如 60 次),失败后应触发告警并退出,而非死等 -
nats.ReconnectWait(2 * time.Second)+nats.ReconnectJitter(100*time.Millisecond, time.Second):固定间隔 + 随机抖动,避免重连风暴 - 加
nats.Name("svc-order-processor"):让服务端能识别客户端身份,便于审计和限流 - 集群部署时 URL 写成逗号分隔:
"tls://n1:4443,tls://n2:4443",客户端自动做初始负载均衡和故障转移
JetStream 启用后,js.Publish() panic 不是代码 bug,是上下文没初始化
很多团队以为开了 JetStream 就自动支持持久化,结果第一次 js.Publish() 就 panic:“nil pointer dereference”。这是因为 NATS 客户端不会在 Connect() 时自动准备 JetStream 上下文 —— 它是独立的、需显式构造的层。
- 连接成功后立刻执行:
js, err := jetstream.New(nc),且必须检查err;如果服务端未启用 JetStream,这里就会失败 - 建议紧接着调一次
js.AccountInfo()做健康探针,失败则提前退出,别等到 publish 才暴露问题 - 流(Stream)创建是一次性动作:
js.AddStream()必须在应用启动早期完成;改配置要删流重建,不是热更新 - 若用嵌入式服务器,确保
server.Options{JetStream: true}已设,且StoreDir可写
去重和顺序控制全靠客户端填对参数,JetStream 不自动保证
“消息重复扣款”“状态乱序更新”这类线上事故,90% 出在发布/订阅两端参数没对齐。JetStream 提供能力,但不替你做业务决策。
立即学习“go语言免费学习笔记(深入)”;
- 去重要生效,发布时必须带
nats.WithMsgID("order-12345"),ID 必须是业务唯一标识(如订单号),不是uuid.New() - 流配置里的
Duplicates: 2*time.Minute是去重窗口,不是消息保留时间;若单条消息处理耗时 >2 分钟,仍会重复 - 多 goroutine 并发
js.Publish()到同一 subject,NATS 不保证顺序;顺序敏感场景必须串行发布,或用单个 goroutine + channel 缓冲 - 订阅时想从头消费历史消息,必须显式加
nats.DeliverPolicy(nats.DeliverAll);默认是跳过已有消息
真正容易被忽略的是:JetStream 的流(Stream)和消费者(Consumer)是服务端资源,不是客户端对象。删流前得确认没其他服务还在用它;Consumer 名字一旦用了 nats.Durable("xxx"),就永久绑定消费位点 —— 改名或删了重建,意味着从头开始消费。这些都不是 connect 配置能解决的,得进运维流程管起来。


















