You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

无需Eureka/Consul等服务注册中心,仅用Ribbon能否实现负载均衡?

可以!无需注册中心,仅用Ribbon就能实现负载均衡

当然没问题!Ribbon本身就支持脱离Eureka/Consul等服务注册中心的独立负载均衡模式,你当前的实现思路完全正确,甚至已经把核心配置都做对了。我来帮你梳理下你的方案,再补充一些需要注意的细节:

核心原理

Ribbon有两种主要工作模式:

  • 集成注册中心:自动从Eureka/Consul拉取服务实例列表并维护
  • 静态配置实例:直接在本地配置文件中指定服务的所有实例地址,不需要依赖任何注册中心,这正是你现在用的方式

你的代码正确性验证

Consumer端配置(完全正确的部分)

  1. @RibbonClient注解:指定了目标服务名ProducerService,并绑定了自定义的Ribbon配置类,这是针对单个服务做Ribbon配置的正确方式。
  2. YAML配置
    • ProducerService.ribbon.eureka.enabled: false:彻底关闭了Ribbon和Eureka的集成,强制使用静态实例列表
    • listOfServers:明确指定了三个Producer实例的地址,Ribbon会基于这个列表做负载均衡
    • ServerListRefreshInterval: 15000:设置实例列表15秒刷新一次,支持动态修改配置后自动生效
  3. @LoadBalanced注解:给RestTemplate添加这个注解是让Ribbon介入HTTP调用的关键,没有它的话http://ProducerService/value这种服务名调用是无法解析的。
  4. 自定义Ribbon规则:你配置的AvailabilityFilteringRule会自动过滤掉故障实例,PingUrl会定期检测实例可用性,这是很实用的生产级配置。

Producer端代码(正确)

你的Producer控制器通过@Value获取当前端口并返回,非常适合用来验证负载均衡的效果,每次调用都能直观看到请求被分发到了哪个实例。

验证步骤

  1. 启动三个Producer实例:分别用--server.port=8081--server.port=8082--server.port=8083作为启动参数,启动三个不同端口的服务。
  2. 启动Consumer实例(端口8080)。
  3. 多次访问http://localhost:8080/hello,你会看到返回结果轮流显示808180828083,这就说明Ribbon的负载均衡已经生效了!

需要注意的细节

  1. 避免全局Ribbon配置污染
    你的RibbonConfig类如果和ConsumerService2Application在同一个包(或子包)下,会被Spring的组件扫描自动加载,变成全局的Ribbon配置,影响所有Ribbon客户端。解决方法:

    • RibbonConfig移到主启动类所在包的外部
    • 或者在@SpringBootApplication中用@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = RibbonConfig.class))排除这个类
  2. PingUrl的健康检查依赖
    你用的PingUrl默认会调用实例的/actuator/health端点来检测可用性,如果你的Producer没有引入Spring Boot Actuator依赖,会导致Ping失败,实例被标记为不可用。解决方法二选一:

    • 给Producer添加Actuator依赖:
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      
      并在Producer的配置文件中开放健康端点:
      management:
        endpoints:
          web:
            exposure:
              include: health
      
    • 改用NoOpPing(不做健康检测,默认所有实例都可用):在RibbonConfig中修改ping方法:
      @Bean
      public IPing ping(IClientConfig clientConfig) {
          return new NoOpPing();
      }
      
  3. 动态更新实例列表
    你设置的ServerListRefreshInterval: 15000意味着每15秒会重新读取一次配置文件中的实例列表,如果你需要添加/移除实例,直接修改Consumer的YAML配置,等待15秒后就会生效,不需要重启Consumer服务。

内容的提问来源于stack exchange,提问作者santhosh margan

火山引擎 最新活动