Beego启动时注册Consul必须显式配置Check字段,否则服务状态为critical且无法被发现;需在app.Run()前完成注册、监听SIGTERM执行deregister、查询时设PassingOnly:true。

Beego 启动时注册服务到 Consul 必须显式传 Check 字段
不填 Check,Consul 会把实例标记为 critical,即使服务进程在跑,调用方也拿不到它。Beego 没有内置注册逻辑,得自己写注册代码,并确保在 app.Run() 前完成。
常见错误现象:服务启动后能在 Consul UI 看到节点,但状态是红色 critical;api.Health().Service("xxx", "", true) 查不到任何实例。
- 必须构造
AgentServiceRegistration,其中Check.HTTP指向 Beego 的健康检查路由(如"http://127.0.0.1:8080/health") -
Check.Timeout要小于Check.Interval,否则 Consul 认为超时失败 - Beego 的
/health路由需手动加,返回 200 即可,不要依赖中间件拦截 404 - 注册前确认 Consul agent 已启动且网络可达,否则
ServiceRegister会阻塞或 panic
Beego 关闭时 deregister 服务不能只靠 defer
Beego 的 app.Run() 是阻塞调用,进程退出信号(如 SIGTERM)不会自动触发 defer,导致服务下线后还在 Consul 里挂着,造成脏数据。
使用场景:Kubernetes 中 Pod 被驱逐、Docker stop、systemd reload 等标准终止流程。
- 用
os.Signal.Notify监听os.Interrupt和syscall.SIGTERM - 在信号处理函数里调用
consulClient.Agent.ServiceDeregister(serviceID) - 调用完 deregister 后再
os.Exit(0),避免app.Run()继续阻塞 - 别在
init()或main()开头就注册——Beego 路由还没加载完,健康检查端点可能 404
Beego 应用查 Consul 服务列表要设 PassingOnly: true
默认 api.Health().Service 返回所有状态的实例(包括 critical、warning),直接拿来负载均衡会打到故障节点。
性能影响:不加过滤会导致客户端缓存大量无效地址,重试成本上升;在高并发下还可能因 DNS 缓存未刷新而持续失败。
- 查询时必须传
PassingOnly: true参数,例如:api.Health().Service("user-service", "", true, &api.QueryOptions{AllowStale: false}) -
AllowStale: false强制读取 leader 数据,避免 etcd backend 下读到过期列表(Consul 默认用 raft,但某些部署启用了 stale 模式) - 别用
net.LookupHost("user-service.service.consul")—— Beego 容器里没配 Consul DNS,会直接报no such host - 建议封装一个
GetHealthyInstances(serviceName string)函数,内部统一处理重试和超时
Beego + Consul 在容器环境要注意 IP 地址上报方式
本地开发用 127.0.0.1 注册没问题,但容器里其他服务连不上——因为 Consul 存的是容器内网 IP,外部调用方无法路由。
容易踩的坑:硬编码 Address 为 "localhost" 或留空,导致注册进 Consul 的地址根本不可达。
- 从环境变量读取宿主机 IP 或 Kubernetes Downward API 提供的
status.hostIP - 或用
net.InterfaceAddrs()扫描非 loopback 网卡,选第一个 IPv4 地址(注意 Docker bridge 和 host 网络模式差异) - Port 必须填 Beego 实际监听的端口,不是容器映射端口(比如 Beego 监听 8080,Docker -p 9090:8080,则填 8080)
- 如果用 Kubernetes headless service,可跳过 Consul,直接走 DNS;但跨集群或混合云场景仍需 Consul
consul/api 客户端。这意味着错误处理、重试、连接池、watch 重建这些事,全得自己兜底——框架不会帮你 catch ErrConnRefused 或自动重连断开的 watch。


















