跳到主要内容

服务发现与负载均衡

如何把服务名解析为可调用实例?​

  • Server: server.WithRegistry + WithServerBasicInfo;
  • Client: client.WithResolver,service name 作为查询键;
  • 直连: 已知地址时跳过发现; 适合本地开发、诊断与固定依赖;
  • 实例元数据: zone、版本、权重、标签可参与路由与均衡;
registry, err := etcd.NewEtcdRegistry([]string{"127.0.0.1:2379"})
if err != nil {
return fmt.Errorf("create registry: %w", err)
}
svr := userservice.NewServer(
new(UserServiceImpl),
server.WithRegistry(registry),
server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "user"}),
)

如何选择负载均衡算法?​

  • WeightedRoundRobin: 默认策略; 按权重轮询;
  • WeightedRandom: 按权重随机; 大样本下趋于均衡;
  • ConsistentHash: 相同 key 尽量命中相同实例; 适合有状态或缓存亲和;
  • Tagging Based: 根据标签筛选与路由多态实例;
  • 自定义: 实现 LoadBalancer 接口,并通过 Client Option 注入;

如何处理实例列表变化?​

  • 服务名: 注册与发现两端必须一致;
  • 更新: Resolver 必须处理新增、删除和权重变化;
  • 空实例: 明确 fail-fast、缓存旧值或降级策略;
  • 一致性哈希: key 不能为空,虚拟节点越多越均匀但构建成本越高;
  • K8s DNS: ClusterIP 只暴露一个地址时,Client 无法感知 Pod 级实例并做严格负载均衡;

如何选择服务发现适配器?​

  • 选择入口: 第三方集成 汇总注册发现适配器及版本约束;
  • 本层职责: 无论控制面选什么产品,Client 最终都需要可用实例、权重和元数据;不要把业务代码绑定到控制面 SDK;