6.5 切换负载均衡策略
- Spring Cloud Ribbon 默认使用轮询策略选取服务实例,我们也可以根据自身的需求切换负载均衡策略。
- 对于切换负载均衡策略,只需要在服务消费者(客户端)的配置类中,将 IRule 的其他实现类注入到容器中即可。
6.5.1 第一种方式 使用配置类
- 例如:在 microservice-cloud-consumer-dept-80 的配置类 ConfigBean 中添加以下代码,将负载均衡策略切换为 RandomRule(随机)。
@Bean
public IRule myIRule(){
// RandomRule 为随机策略
return new RandomRule();
}
切换负载均衡策略和自定义负载均衡策略需要导入低版本的spring-cloud-starter-netflix-eureka-client。由于使用的spring-cloud-starter-netflix-eureka-client版本太高,并且没有实现
@LoadBalanced
接口,就会报错需要实现 LoadBalanceClient 接口。而Ribbon需要结合具体的客户端去实现。同时如果不在项目中实现该接口,必须使用带有与ribbon结合的工具库的包如图所示(新版本已将其丢弃)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
- 3.0.4版本
- 2.2.9.RELEASE版本
在导入依赖时,尽可能让前缀相同的依赖使用相同的版本!
- 在 microservice-cloud-consumer-dept-80 的主启动类上,使用 @RibbonClients 注解来让我们切换的的负载均衡策略生效,代码如下。
package com.example;
import com.example.config.FeignConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.openfeign.EnableFeignClients;
//OpenFeign和Eureka整合以后,容户端可以直接调用用,不用关心服务的IP地址和端口号
@SpringBootApplication
@EnableEurekaClient
// 如果只有一个服务就可以直接使用@RibbonClient注解,而不需要@RibbonClients。
// name是写服务提供方的服务名 configuration是指定我们上面创建的配置类
@RibbonClients(value = {
@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT",configuration = FeignConfiguration.class)
})
//@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT",configuration = FeignConfiguration.class)
public class MicroserviceCloudConsumerDeptOpenFeignApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceCloudConsumerDeptOpenFeignApplication.class, args);
}
}
- 重启 microservice-cloud-consumer-dept-80,使用浏览器访问“http://eurekaserver7001.com/app/consumer/dept/list”或http://localhost/app/consumer/dept/list,结果如下图。负载均衡策略切换为 RandomRule(随机)。不断刷新链接,发现数据来源集中于springcloud_db3和springcloud_db_core
6.2.2 第二种方式 使用yaml配置
- 在 micro-service-cloud-provider-dept-8003 中 application.yml 中,修改的这种负载均衡算法
#设置负载均衡策略 eureka-provider 为调用的服务的名称 value为策略全限定名
eureka-provider:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
6.6 自定义负载均衡策略
- 通常情况下,Ribbon 提供的这些默认负载均衡策略是可以满足我们的需求的,如果有特殊的要求,我们还可以根据自身需求定制负载均衡策略。
- 测试下自定义负载均衡策略,在 microservice-cloud-consumer-dept-80 中新建一个 com.myrule 包,并在该包下创建一个名为 MyRibbonRule的类(里面具体的实现可以仿照Ribbon下loadbalancer的接口IRule的实现类RandomRule),代码如下。
package com.myrule;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
/**
* 定制 Ribbon 负载均衡策略
*/
public class MyRibbonRule extends AbstractLoadBalancerRule{
private int index = 0; // 当前提供服务的机器号
private int total = 0; //总共被调用的次数,目前要求每台被调用3次
public MyRibbonRule() {
super();
}
@Override
public void setLoadBalancer(ILoadBalancer lb) {
setLoadBalancer(lb);
}
@Override
public ILoadBalancer getLoadBalancer() {
return getLoadBalancer();
}
@Override
public Server choose(Object key) {
return null;
}
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
//获取所有有效的服务实例列表
List<Server> upList = lb.getReachableServers();
//获取所有的服务实例的列表
List<Server> allList = lb.getAllServers();
//如果没有任何的服务实例则返回 null
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
if(total < 3){
//从有效的服务选择 index = (total++)/ 3 % 3 0开始
server = upList.get(index);
total++;
}else {
total = 0;
index++;
if (index >= upList.size()){
index = 0;
}
}
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
server = null;
Thread.yield();
}
return server;
}
}
- 在 com.myrule 包下创建一个名为 MyRibbonRuleConfig 的配置类,将我们定制的负载均衡策略实现类注入到容器中,代码如下。
该自定义 Ribbon 负载均衡策略配置类不能在 com.example 包及其子包下也就是不能和启动类同级,否则将会被启动类扫描到@ComponentScan导致所有的 Ribbon客户端都会采用该策略,无法达到特殊化定制的目的
package com.myrule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//定制 Ribbon 负载均衡策略的配置类
@Configuration
public class MyRibbonRuleConfig {
@Bean
public MyRibbonRule myRibbonRule(){
return new MyRibbonRule();
}
}
- 修改位于 com.example包下的主启动类,在该类上使用 @RibbonClient 注解让我们定制的负载均衡策略生效。
- 自定义 Ribbon 负载均衡策略在主启动类上使用 RibbonClient 注解,在该微服务启动时,就能自动去加载我们自定义的 Ribbon 配置类,从而使默认配置生效
- name 为需要定制负载均衡策略的微服务名称(application name)
- configuration 为定制的负载均衡策略的配置类
- 官方文档中明确提出,该配置类不能在 ComponentScan 注解(SpringBootApplication 注解中包含了该注解)下的包或其子包中,即自定义负载均衡配置类不能在 com.example 包及其子包下
//Ribbon和Eureka整合以后,容户端可以直接调用用,不用关心服务的IP地址和端口号
@SpringBootApplication
@EnableEurekaClient
//在微服务启动的时就能去加载我们自定义Ribbon类
@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT",configuration = MyRibbonRuleConfig.class)
public class MicroserviceCloudConsumerDept80Application {
public static void main(String[] args) {
SpringApplication.run(MicroserviceCloudConsumerDept80Application.class, args);
}
}
-
重启 microservice-cloud-consumer-dept-80,使用浏览器访问“http://localhost/app/consumer/dept/list”,结果如下图。同一个服务的数据刷新5次后,改变为另一个服务的数据
-
从上图中的dbSource 字段取值的变化可以看出,我们定制的负载均衡策略已经生效。
下一篇:SpringCloud-17-OpenFeign:Feign 介绍
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123812.html