什么是Ribbon
目前主流的负载均衡器有以下两种
- 服务端负载均衡
集中式负载均衡,在消费和服务提供方之间使用独立的代理方式进行负载,有硬件的(比如F5与交换机进行连接),也有软件的比如(nginx)
- 客户端负载均衡
客户端根据自己的请求情况做负载均衡,Rbbion就属于客户端自己做负载均衡
Spring Cloud Ribbon是基于Netflix Ribbon 实现的一套
客户端的负载均衡工具,
Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。通过
Load Balancer
获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法。
客户端的负载均衡
例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是 客户端负载均衡;即在客户端就进行负载均衡算法分配。
![](https://i-blog.csdnimg.cn/blog_migrate/60f8a4313c78bad946808f087e9f78c8.png)
服务端的负载均衡
例如Nginx,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进行负载均衡算法分配。
![](https://i-blog.csdnimg.cn/blog_migrate/abac35ca0136b00d7aec73741e4c8865.png)
常见负载均衡算法
随机:通过随机选择服务进行执行,一般这种方式用的很少
轮训:负载均衡默认实现方式,请求来之后排队处理
加权轮训:通过对服务器性能的分析,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力
地址hash:通过客户端请求的地址的hash值取模映射进行服务器调度。ip -->hash
最小连接数:及请求均衡了压力不一定均衡,最小连接数法就是根据服务器的情况,比如请求积压参数等参数,将请求分配到当前压力最小的服务器上。最小活跃数
Nacos使用Ribbon
nacos-discovery依赖了ribbon,可以不用再引入ribbon依赖
第二步添加@LoadBalance注解
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
第三步修改controller
@RestController
@RequestMapping("/order")
public class OrderController {
@Resource
private RestTemplate restTemplate;
@RequestMapping("/add")
public String add() {
System.out.println("下单成功!");
// 用spring-boor的resTemplate 实现服务与服务之间的调用(不用自己再手动序列化反序列化)
// String msg = restTemplate.getForObject("http://127.0.0.1:8082/stock/reduce", String.class);
String msg = restTemplate.getForObject("http://stock-service/stock/reduce", String.class);
return "hello word"+msg;
}
}
Ribbon负载均衡策略
IRule
这是所有负载均衡策略的父接口,
里边的核心方法就是
choose
方法,用来选择一个服务实例
。
AbstractLoadBalancerRule
AbstractLoadBalancerRule
是一个抽象类,里边主要定义了一个
ILoadBalancer
,这里定义它的目的主要是
辅助负责均衡策略选取合适的服务端实
例。
- RandomRule :随机选择一个实例
- RandomRbbionRule:轮训负载均衡策略
- RetryRule:在轮训的基础上添加重试功能,在接口请求不超时的情况下一个服务实列请求失败会不断请求其它健康的服务实例
-
WeightedResponseTimeRule:权重,如果一个服务的平均响应时间越短则权重越大,那么该服务实例被选中执行任务的概率也就越大
- ClientConfigEnabledRoundRobinRule :轮训负载均衡策略
-
BestAvailableRule:过滤掉失效掉的服务实例功能,然后再找出请求并发实例最小的实例服务来调用
- ZoneAvoidanceRule:默认规则,选择就近的分区服务,然后再根据轮询策略选择实例服务
-
AvailabilityFilteringRule: 先过滤掉故障实例,再选择并发较小的实例
修改默认负载均衡策略
通过配置类
@Configuration
public class RibbonConfig {
/**
* 全局配置
* 指定负载均衡策略
* @return
*/
@Bean
public IRule iRule() {
// 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机权重)
return new NacosRule();
}
}
注意:此处有坑。
不能写在@SpringbootApplication注解的@CompentScan扫描得到的地方,否则自定义的配置类就会被所有的RibbonClients共享。 不建议这么使用,推荐yml方式
![](https://i-blog.csdnimg.cn/blog_migrate/411985c8de75ef0580b8505d35561598.png)
然后在启动类上
利用@RibbonClient指定微服务及其负载均衡策略。
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
DruidDataSourceAutoConfigure.class})
//@RibbonClient(name = "mall‐order",configuration = RibbonConfig.class)
//配置多个 RibbonConfig不能被@SpringbootApplication的@CompentScan扫描到,否则就是全局配置的效果
@RibbonClients(value = {
// 在SpringBoot主程序扫描的包外定义配置类
@RibbonClient(name = "mall‐order",configuration = RibbonConfig.class),
@RibbonClient(name = "mall‐account",configuration = RibbonConfig.class)
})
public class MallUserRibbonDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MallUserRibbonDemoApplication.class, args);
}
}
通过配置文件
调用指定微服务提供的服务时,使用对应的负载均衡算法
修改配置文件application.yml
# 被调用的微服务名 及服务提供方
mall‐order:
ribbon:
# 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重)
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRul
注意:权重自己可以在yml文件里边根据参数设置权重
也可以在nacos管理平台上对对应的实例服务设置权重
自定义负载均衡策略
只需要继承AbstractLoadBalancerRule类 并实现它的choose方法
配置自定义的策略
# 被调用的微服务名
mall‐order:
ribbon:
# 自定义的负载均衡策略(基于随机&权重)
NFLoadBalancerRuleClassName: 自定义负载均衡策略配置类的全类名
设置饥饿加载
在进行服务调用的时候,如果网络情况不好,第一次调用会超时。
Ribbon默认懒加载,意味着只有在发起调用的时候才会创建客户端。
开启饥饿加载,解决第一次调用慢的问题。程序启动的时候就初始化了负载均衡策略
ribbon:
eager‐load:
# 开启ribbon饥饿加载
enabled: true
# 配置mall‐user使用ribbon饥饿加载,多个使用逗号分隔
clients: stock-service