Bootstrap

SpringCloudAlibaba - 整合 Ribbon 实现负载均衡

前言

Ribbon是一个Netflix开源的客户端侧负载均衡器,其提供了丰富的负载均衡算法,服务消费者集成Ribbon后,Ribbon会自动从Nacos Server获取想要调用的服务的地址列表,通过负载均衡算法计算出一个实例交给RestTemplate调用


注:Spring Cloud 2020 已移除对 Ribbon 的支持,相应的,Spring Cloud 2021 版本 Nacos 中 也删除了Ribbon 的 jar 包,实现时需要注意版本依赖关系


环境

Spring Cloud Hoxton.SR9 + Spring Cloud Alibaba 2.2.6.RELEASE


简单示例

  • spring-cloud-starter-alibaba-nacos-discovery中默认包含Ribbon,所以不需要添加依赖

在这里插入图片描述


这里的示例代码是内容中心(content-center)通过调用用户中心(user-center)的两个实例看是否实现负载均衡


user-center

  • TestController.java
@RestController
@Slf4j
public class TestController {

    @GetMapping("/test/{name}")
    public String test(@PathVariable String name) {
    	log.info("请求...");
        return "hello " + name;
    }

}
  • 用户中心以80818082端口启动

在这里插入图片描述


在这里插入图片描述



content-center

  • 启动类
/**
 * @LoadBalanced 为RestTemplate 整合Ribbon
 */
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}
  • TestController.java
@RestController
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TestController {

	private final RestTemplate restTemplate;

    /**
     * 整合Ribbon
     * @return
     */
    @GetMapping("test3")
    public String test3() {
        /**
         * RestTemplate 请求时,ribbon会把user-center转换成用户中心在Nacos上的地址,
         * 进行负载均衡算法计算出一个实例去请求
         */
        return restTemplate.getForObject(
                "http://user-center/test/{name}",
                String.class,
                "Coisini"
        );
    }
}

测试

  • 访问接口测试,可以发现Ribbon以轮询的方式实现负载均衡

在这里插入图片描述
在这里插入图片描述


Ribbon 的组成和默认的负载均衡规则

Ribbon 的组成

  • Ribbon为所有的组件提供了接口,如果对默认值不满意,可以实现这些接口进行二次开发
接口作用默认值
IClientConfig读取配置DefaultClientConfigImpl
IRule负载均衡规则,选择实例ZoneAvoidanceRule
IPing筛选掉ping不通的实例DummyPing
ServerList< Server>交给Ribbon的实例列表Ribbon:ConfigurationBasedServerList
Spring Cloud Alibaba: NacosServerList
ServerListFilter< Server>过滤掉不符合条件的实例ZonePreferenceServerListFilter
ILoadBalancerRibbon的入口ZoneAwareLoadBalancer
ServerListUpdater更新交给Ribbon的List的策略PollingServerListUpdater

Ribbon 默认的负载均衡规则

  • Ribbon默认的负载均衡规则是ZoneAvoidanceRule,在没有zone的情况下默认是轮询
  • Ribbon内置的负载均衡规则如下
规则名称特点
AvailabilityFilteringRule过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就是检查status里记录的各个Server的运行状态
BestAvailableRule选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过
RandomRule随机选择一个Server
ResponseTimeWeightedRule已废弃,作用同WeightedResponseTimeRule
RetryRule对选定的负载均衡策略机上重试机制,在同一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的Server
RoundRobinRule轮询选择,轮询index,选择index对应位置的Server
WeightedResponseTimeRule根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低
ZoneAvoidanceRule复合判断Server所在Zone的性能和Server的可用性选择Server,在没有Zone的环境下,类似于轮询(RoundRobinRule)

Ribbon 的自定义配置

实现目的:通过自定义配置实现随机选择


Java 代码配置方式

  • UserCenterRibbonConfiguration.java
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;
import ribbonconfiguration.RibbonConfiguration;

/**
 * @Description 用户中心配置类
 */
@Configuration
@RibbonClient(name = "user-center", configuration = RibbonConfiguration.class)
public class UserCenterRibbonConfiguration {
}
  • RibbonConfiguration.java
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Ribbon的配置类
 *      Ribbon的配置类要有@Configuration注解,但不能被@ComponentScan重复扫描
 *      否则就会被所有的RibbonClient共享
 */
@Configuration
public class RibbonConfiguration {

	/**
     * 自定义负载均衡规则
     * RandomRule 随机选择
     * @return
     */
    @Bean
    public IRule ribbonRule() {
        return new RandomRule();
    }
}
  • 目录结构如下所示,Ribbon配置类RibbonConfiguration.java位置在java目录下,其作用是避免父子上下文重叠,Ribbon的配置类要有@Configuration注解,但不能被@ComponentScan重复扫描,否则就会被所有的RibbonClient共享

在这里插入图片描述

  • 接口访问测试发现随机访问已实现

在这里插入图片描述
在这里插入图片描述


yml 属性配置方式

  • 注释Java代码配置方式中的代码,在application.yml中添加user-center的负载均衡规则,也能实现相同的效果
user-center:
  ribbon:
    # Ribbon负载均衡规则的全路径
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Ribbon 的全局配置

  • 有自定义配置就有全局配置,可以通过修改@RibbonClient注解为@RibbonClients注解实现全局配置
  • UserCenterRibbonConfiguration.java
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Configuration;
import ribbonconfiguration.RibbonConfiguration;

/**
 * @Description 用户中心配置类
 */
@Configuration
@RibbonClients(defaultConfiguration = RibbonConfiguration.class)
public class UserCenterRibbonConfiguration {
}
  • RibbonConfiguration.java
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Ribbon的配置类
 */
@Configuration
public class RibbonConfiguration {

	/**
     * 自定义负载均衡规则
     * RandomRule 随机选择
     * @return
     */
    @Bean
    public IRule ribbonRule() {
        return new RandomRule();
    }
}

Ribbon 的饥饿加载

  • 默认情况下Ribbon是懒加载的,当RestTemplate第一次调用RibbonClient时才会创建一个client,这样会导致首次请求过慢或失败的问题,可以通过属性配置开启Ribbon的饥饿加载

  • application.yml

ribbon:
  eager-load:
    # 开启饥饿加载
    enabled: true
    # 为哪些RibbonClient开启饥饿加载,多个用 "," 隔开
    clients: user-center

项目源码



- End -
- 个人学习笔记 -
- 仅供参考 -

;