← 返回博客
go2026-09-12 22:13:422 分钟 · 516 0

服务注册发现与配置中心:consul 与 k8s 原生

服务实例多了,地址怎么找、配置怎么统一下发。讲清客户端/服务端发现、consul 注册发现、以及 k8s 下用 Service+ConfigMap 代替独立组件。

1. 为什么需要注册发现

服务 A 调服务 B,B 有 5 个实例,地址会变(扩缩容、重启)。把地址写死在配置里维护不动。注册发现让 B 启动时上报、A 运行时查可用实例。

2. 两种发现模式

服务端发现:A 问网关/B 问注册中心,由中间层挑实例(k8s Service 就是)。客户端发现:A 自己从注册中心拿实例列表挑一个(Consul + 客户端负载均衡)。

3. consul 注册

reg := &consul.AgentServiceRegistration{
    Name: "order-svc", Port: 8080,
    Check: &consul.AgentServiceCheck{HTTP: "http:///healthz", Interval: "10s"},
}
consul.Agent().ServiceRegister(reg)
// 关时注销(第 8 篇优雅停机里调)

健康检查挂 healthz(第 8 篇),不健康的实例被摘掉。

4. 客户端取实例

func pick(service string) string {
    entries, _ := consul.Health().Service(service, "", true, nil)
    return entries[rand.Intn(len(entries))].Service.Address + ":" + port
}

拿到健康实例随机挑(或轮询)。配合第 2 篇的 gRPC Dial 复用连接。

5. 配置中心

多服务共享的配置(限流阈值、特性开关、下游地址)集中管,改了下发不重启:

kv.Get("order-svc/ratelimit", &cfg) // consul kv 或 nacos;k8s 用 ConfigMap 挂进容器

第 7 篇的热加载对接这里,配置改了各服务热加载生效。

6. k8s 原生替代

上了 k8s 大多不用 consul:Service 名做发现(order-svc.default.svc)自带 DNS 和负载均衡,ConfigMap/Secret 做配置,探针做健康检查。注册发现交给平台,代码里只填服务名:

conn, _ := grpc.Dial("order-svc:8081", ...) // k8s 解析到实例

7. 上线清单

实例地址别写死,用发现或 k8s Service。注册时带健康检查,不健康实例自动摘。配置集中到配置中心或 ConfigMap,改动热下发。k8s 环境优先用原生 Service+ConfigMap,少引独立组件。客户端发现要自己处理实例列表缓存和刷新,别每次请求查注册中心。

六篇走完,第三季从微服务拆分、gRPC、事件驱动、DDD、分布式事务到注册发现,把单个 Gin 服务放到分布式系统里该怎么长讲清了。三季合计从入门到架构,一条完整的学习路径。

相关推荐

本文为原创文章,采用CC BY-NC-SA 4.0协议授权,转载请保留署名与原文链接。原文链接:https://www.wxbuluo.com/article/204