Go微服务负载均衡需构建服务发现、健康状态、策略选择闭环。须用watch监听实例变更并本地缓存,基于LastHealthyAt标记不健康节点,维护动态可用节点切片,失败节点熔断,高频扩缩容宜用least_request或加盐+虚拟节点的一致性哈希。
Go 微服务做负载均衡,不是配个库就完事——关键在于把 服务发现、节点健康状态 和 策略选择逻辑 三者串成闭环。硬编码地址或只用 gRPC 默认 round_robin 在生产环境大概率出问题。
很多团队一开始用 consul.Health().Service() 每 5 秒主动查一次,结果注册中心压力大、本地列表滞后、扩缩容延迟高。
watch 机制监听变更:Consul 用 WatchPlan,etcd 用 clientv3.Watcher,收到事件后原子替换本地 sync.Map 中的 map[string]*Instance
LastHealthyAt 时间戳,超过 30 秒没心跳就标记为 unhealthy,不参与调度看似最简单的 atomic.AddInt64(&idx, 1) % len(nodes),实际会因节点动态剔除导致索引越界或跳过健康节点。
rpc: server error 或连接超时),不能只跳过这一次—
least_request 或带权重的一致性哈希,比纯轮询更抗抖动直接对 user_id 做 sha256 取模,遇上 ID 连续或大量 0 值,流量全打到同一台机器上是常态。
"user-svc-prod")拼接后再哈希,打破输入规律github.com/serialx/hashring 而不是手写环结构真正难的从来不是实现某个算法,而是让 节点列表更新、健康探测、策略执行 和 调用反馈 四件事在毫秒级完成且互不干扰。漏掉任意一环,再漂亮的轮询代码也只会把流量稳稳导进故障节点里。