NATS单机调试需用Docker启动服务并验证端口与健康状态,连接时优先用"localhost:4222"而非127.0.0.1,启用JetStream须显式配置--js-enabled=true及nats.JetStream()选项。

单机调试 NATS 时,nats-server 必须运行在本地且与 Go 程序使用同一网络命名空间(默认 localhost),否则 net.Dial 会报 dial tcp 127.0.0.1:4222: connect: connection refused —— 这不是代码问题,而是服务根本没起来或端口被占。
怎么确认 nats-server 已正确启动并监听 4222
GoLand 本身不内置 NATS 服务,必须手动启动或通过 Docker 启动。本地开发最稳妥的方式是用 Docker:
- 运行
docker run -d --name nats -p 4222:4222 -p 8222:8222 nats:2.10.14(推荐固定小版本,避免行为突变) - 检查端口:执行
nc -zv 127.0.0.1 4222,返回succeeded才算通 - 验证服务健康:访问
http://localhost:8222/healthz,HTTP 200 表示服务就绪 - 别用
nats-server -js直接前台启动——GoLand 调试时若混入前台进程,容易阻塞 Run Configuration 启动流程
GoLand 中 client 连接 NATS 的常见配置陷阱
Go 代码里用 nats.Connect("nats://127.0.0.1:4222") 看似合理,但在某些 macOS + Docker Desktop 组合下会失败,因为 Docker 的 host.docker.internal 解析不稳定。更可靠的做法是:
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
- 统一用
"nats://localhost:4222",不是127.0.0.1—— macOS 上两者 DNS 解析路径不同,localhost更稳定 - 加超时和重连控制:
nats.Connect("localhost:4222", nats.MaxReconnects(-1), nats.ReconnectWait(500*time.Millisecond)) - 如果项目启用了 JetStream,务必在 Run Configuration 的
Program arguments里显式传--js-enabled=true,并在连接时加nats.JetStream()选项,否则js, err := nc.JetStream()会返回nil, nil - 环境变量如
NATS_URL优先级高于硬编码地址,调试时建议清空该变量,避免被 CI 配置污染本地行为
调试时如何观察 NATS 消息收发链路
仅靠日志很难定位消息是否真正 publish 成功、consumer 是否及时 ack。GoLand 自带的 Services 工具窗口无法显示 NATS 流量,需借助外部手段:
- 启动一个监控终端:
docker exec -it nats nats sub ">",可实时看到所有主题消息(需先安装natsCLI 工具) - 在 Go 代码中对
js.PublishAsync的Future显式调用Wait()并捕获 error,否则异步 publish 失败会被静默吞掉 - 设置断点时避开
js.Subscribe的回调函数内部——NATS 回调在线程池中执行,GoLand 默认不挂起该 goroutine,建议在回调开头加runtime.Breakpoint()强制中断 - 不要依赖
js.ConsumerInfo的NumAckPending字段判断积压,它只反映未 ack 的消息数,不包含正在处理中的;真要看处理状态,得结合js.StreamInfo().State.Msgs和 consumer 的LastDelivered
最容易被忽略的是 JetStream 的 stream 和 consumer 创建时机:它们不是幂等操作,重复执行会报 stream name already in use 错误。调试阶段建议在 main() 开头加 js.DeleteStream("mystream") 清理,或改用 js.AddStream(&nats.StreamConfig{...}, nats.DuplicateErr(false)) 避免中断调试流。

















