9.4.5 客户端负载均衡与就近访问策略

5. 客户端负载均衡与就近访问策略#

客户端负载均衡由服务调用方在本地完成实例选择:订阅实例列表→维护本地缓存与健康状态→按策略选择实例→失败重试或切换。适合结合业务上下文做精细化控制与就近访问。

原理草图#

文章图片

负载均衡策略与就近访问要点#

  • 轮询/加权轮询:按权重分配流量,适合实例性能差异大。
  • 随机/加权随机:分布更均匀,避免周期性热点。
  • 最少连接/最短响应:需收集实时指标,适合低延迟场景。
  • 一致性哈希:保持会话/缓存命中,减少跨实例抖动。
  • 区域优先:同集群/同机房优先,跨地域降级。
  • 标签路由:按 metadata 标记灰度、金丝雀、版本隔离。

安装与基础示例(Nacos + Java 客户端)#

1)启动 Nacos(单机)

# 假设已下载 nacos-server-2.x.tar.gz
tar -xzf nacos-server-2.x.tar.gz -C /opt/
cd /opt/nacos/bin
# 单机模式启动
./startup.sh -m standalone
# 预期:8080 端口启动
ss -lntp | grep 8848

2)注册服务实例并设置 metadata(示例 HTTP API)

# 注册服务并标注 region/zone/weight
curl -X POST "http://127.0.0.1:8848/nacos/v1/ns/instance" \
  -d "serviceName=order-service" \
  -d "ip=10.0.1.10" \
  -d "port=8081" \
  -d "weight=2" \
  -d "metadata.region=cn-hz" \
  -d "metadata.zone=az1"

curl -X POST "http://127.0.0.1:8848/nacos/v1/ns/instance" \
  -d "serviceName=order-service" \
  -d "ip=10.0.2.20" \
  -d "port=8081" \
  -d "weight=1" \
  -d "metadata.region=cn-sh" \
  -d "metadata.zone=az2"

3)客户端负载均衡与就近访问示例(Spring Cloud Alibaba)
- 配置文件 application.yml

spring:
  application:
    name: order-client
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        # 就近访问:优先同集群
        cluster-name: cn-hz
        # 元数据过滤:只选择标记为 prod 的实例
        metadata:
          env: prod
    loadbalancer:
      # 开启权重优先策略(基于 Nacos 权重)
      nacos:
        enabled: true
  • Java 代码(选择实例 + 自定义就近策略简化示例)
// 伪代码,展示实例过滤与权重选择逻辑
List<Instance> instances = namingService.selectInstances("order-service", true);

// 1) 优先同集群/同zone
List<Instance> sameCluster = instances.stream()
    .filter(i -> "cn-hz".equals(i.getClusterName()))
    .collect(Collectors.toList());

// 2) 如果同集群为空,降级到所有实例
List<Instance> candidates = sameCluster.isEmpty() ? instances : sameCluster;

// 3) 按权重随机选择
Instance selected = WeightRandom.selectByWeight(candidates);

// 4) 发送请求

命令验证与预期效果#

# 查询服务实例列表
curl "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=order-service"

# 预期:返回包含 region/zone/weight 的实例信息
# 当客户端 cluster-name=cn-hz 时,优先选择 cn-hz 集群实例

失败重试与熔断示例(配置)#

# application.yml
resilience4j:
  retry:
    instances:
      orderService:
        maxAttempts: 3
        waitDuration: 300ms
        enableExponentialBackoff: true
        exponentialBackoffMultiplier: 2
  circuitbreaker:
    instances:
      orderService:
        failureRateThreshold: 50
        waitDurationInOpenState: 5s
        slidingWindowSize: 10

排错要点与命令#

1)客户端未命中就近实例
- 检查实例元数据与集群名是否一致

# 查看实例详情
curl "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=order-service" \
| jq '.hosts[] | {ip,clusterName,metadata}'
  • 检查客户端配置 cluster-name 是否正确
grep -R "cluster-name" -n config/ application.yml

2)实例列表为空
- 检查 Nacos 注册是否成功、心跳是否正常

# 查看 Nacos 日志
tail -f /opt/nacos/logs/nacos.log

3)负载不均或热点
- 检查权重设置与策略

# 修改权重
curl -X PUT "http://127.0.0.1:8848/nacos/v1/ns/instance" \
  -d "serviceName=order-service" \
  -d "ip=10.0.1.10" \
  -d "port=8081" \
  -d "weight=5"

练习#

1)注册三台实例,设置不同 region/zone/weight,验证客户端优先同集群。
2)模拟一台实例下线,观察客户端重试与熔断是否生效。
3)将负载策略从权重随机切换为一致性哈希,比较缓存命中率变化。