9.9.4 负载均衡与服务发现协作

负载均衡与服务发现协作#

在Spring Cloud生态中,Nacos负责服务注册与发现,负载均衡组件(Spring Cloud LoadBalancer或Ribbon)基于服务发现结果进行实例选择。本节通过流程图、配置示例、排错步骤与练习,落地协作机制。

原理与协作流程图#

文章图片

快速示例:Nacos + Spring Cloud LoadBalancer#

1)服务提供者注册(application.yml)

# file: provider/src/main/resources/application.yml
server:
  port: 8081
spring:
  application:
    name: demo-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: public
        group: DEFAULT_GROUP
        metadata:
          zone: bj
        weight: 1

2)服务消费者调用与负载均衡(application.yml + 代码)

# file: consumer/src/main/resources/application.yml
server:
  port: 8082
spring:
  application:
    name: demo-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
// file: consumer/src/main/java/com/example/DemoController.java
@RestController
public class DemoController {
    private final RestTemplate restTemplate;

    public DemoController(RestTemplateBuilder builder) {
        this.restTemplate = builder.build();
    }

    @GetMapping("/call")
    public String call() {
        // 通过服务名调用,LB会从Nacos实例列表中选择
        return restTemplate.getForObject("http://demo-provider/hello", String.class);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

3)启动与验证命令

# 启动Nacos(已安装)
cd /opt/nacos/bin
./startup.sh -m standalone

# 启动provider/consumer服务(示例)
cd /opt/demo/provider && mvn -q spring-boot:run
cd /opt/demo/consumer && mvn -q spring-boot:run

# 验证服务注册
curl -s "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=demo-provider" | jq '.'

# 验证负载均衡调用
curl -s http://127.0.0.1:8082/call

命令解释
- startup.sh -m standalone:以单机模式启动Nacos。
- instance/list:查询服务实例列表,确认注册成功。
- 访问/call:验证负载均衡是否能通过服务名路由到实例。

权重与元数据协同示例#

# 调整实例权重(影响权重轮询)
curl -s -X PUT \
  "http://127.0.0.1:8848/nacos/v1/ns/instance" \
  -d "serviceName=demo-provider&ip=127.0.0.1&port=8081&weight=2"

# 设置灰度标记(用于路由)
curl -s -X PUT \
  "http://127.0.0.1:8848/nacos/v1/ns/instance" \
  -d "serviceName=demo-provider&ip=127.0.0.1&port=8081&metadata=version=v2"

预期效果
- 权重提升后,该实例被选中概率增加。
- metadata可供网关/自定义LB规则使用,进行灰度发布。

负载均衡策略要点与适用#

  • 轮询:实例性能接近,负载平稳。
  • 权重轮询:新旧版本并行、不同规格机器。
  • 最少连接/响应时间:请求耗时差异大。
  • 随机:实例数量大、分布均匀。

缓存一致性与变更推送说明#

# file: consumer/src/main/resources/application.yml
spring:
  cloud:
    nacos:
      discovery:
        # 拉取间隔(秒),与推送机制配合降低陈旧
        watch-delay: 30000
  • 本地缓存提升可用性,推送+拉取降低陈旧风险。
  • 生产中倾向最终一致性,配合超时/重试避免故障扩散。

排错清单(带命令)#

1) 服务列表为空

# 检查命名空间/分组/服务名
curl -s "http://127.0.0.1:8848/nacos/v1/ns/service/list?pageNo=1&pageSize=50" | jq '.'
  • 关注namespacegroup是否匹配,服务名是否一致。

2) 实例频繁抖动

# 查看Nacos日志(路径视安装而定)
tail -f /opt/nacos/logs/nacos.log
  • 检查心跳阈值、网络抖动、时钟偏差。

3) 流量倾斜

# 查看实例权重与健康
curl -s "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=demo-provider" | jq '.hosts[] | {ip,port,weight,healthy}'
  • 核查权重、实例性能差异、缓存是否更新。

4) 跨环境误调用
- 核对namespacegroupmetadata路由规则。

练习#

1) 部署两个demo-provider实例(端口8081/8083),设置权重1和3,验证调用比例差异。
2) 给其中一个实例设置metadata=version=v2,用自定义负载规则仅路由v2实例。
3) 通过停止其中一个实例,观察消费者是否能在缓存失效后自动剔除。