目标:每个服务都访问5次之后再切换下一个服务
Ribbon自带的负载均衡算法:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200319101221150.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25vdjR0aA==,size_16,color_FFFFFF,t_70)
RoundRobinRule,轮询算法, 轮询index,选择index对应位置的ServerZoneAvoidanceRule(默认),复合判断Server所在Zone的性能和Server的可用性选择Server,在没有Zone的情况下类是轮询RandomRule,随机算法,随机选择一个ServerRetryRule,对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功, 则一直尝试使用subRule的方式选择一个可用的serverAvailabilityFilteringRule,过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个Server的运行状态BestAvailableRule,选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过WeightedResponseTimeRule,根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低
自定义Ribbon负载均衡算法的注意事项:
注意:官方文档中有指出,自定义的类不能放在@ComponentScan或SpringBootApplication所扫描的当前包以及子包下,否则自定义的这个配置类将会被所有的Ribbon客户端所共享。![在这里插入图片描述](https://img-blog.csdnimg.cn/2020031910041673.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25vdjR0aA==,size_16,color_FFFFFF,t_70)
实现步骤:
1、在启动器的上一级创建一个包存放自定义算法的文件 2、找到一个自带的负载均衡算法,以随机算法为例,将RandomRule的代码拿出来,修改一下新的文件名。自定义算法必须继承于AbstractLoadBalancerRule类
package com.demo.myrule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class RandomRule_Test extends AbstractLoadBalancerRule {
public RandomRule_Test() {
}
private int total=0; //当前调用次数
private int currentIndex=0; //当前被引用的服务
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
} else {
Server server = null;
while(server == null) {
if (Thread.interrupted()) {
return null;
}
List upList = lb.getReachableServers();
List allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
//自定义的负载均衡算法
if (totalupList.size()-1){
currentIndex=0;
}
server=upList.get(currentIndex);
}
/*
Ribbon自带的一个获取随机Server的算法
int index = this.chooseRandomInt(serverCount);
server = (Server)upList.get(index);
*/
if (server == null) {
Thread.yield();
} else {
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
}
return server;
}
}
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
public Server choose(Object key) {
return this.choose(this.getLoadBalancer(), key);
}
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
3、将自定义的负载均衡算法注入到Bean中,在自定义算法的文件同级创建一个配置类
package com.demo.myrule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Rule_Test {
@Bean
public IRule myRule(){
//需要什么算法就new对应的类
return new RandomRule_Test();
}
}
4、在启动类中添加Ribbon注解
package com.demo.springcloud;
import com.demo.myrule.Rule_Test;
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;
@SpringBootApplication
@EnableEurekaClient
//name:针对哪个服务,configuration:使用什么算法类
@RibbonClient(name = "SPRINGCLOUD.PROVIDER-DEPT",configuration = Rule_Test.class)
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
5、测试,将7001端口的服务注册中心启动,然后启动8001,8002,8003以及80端口的负载均衡微服务,在访问80负载均衡客户端请求时,每次刷新的结果都是按照我们写的这个负载均衡算法去执行,就算达成效果了
|