阅读之前先阅读
https://blog.csdn.net/dtttyc/article/details/88817129
LB一般是在分布式或者集群中提及, 为了就是可以让不同服务访问均匀,或者根据不同配置可以路由到不同服务,一般我们常见的负载均衡就是nginx
LB 他的形式一般有两种,Ribbon就属于进程内的LB,LB把业务逻辑集成到消费方,由消费方去注册中心(Eureka)获取使用哪些服务,
首先我们先简单的使用一下Ribbon
Ribbon的配置一般都是在消费端
@Bean
@LoadBalanced //负载均衡
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
首先说明以下@bean是要和@Configuration一起使用的,相当于我们的application.yml文件
//他们两个表示的意思是一样的
@Bean
public UserService getUserService(){
return new UserServiceIml();
}
<bean id="userService" class="com.atguitu.springcloud/user.iml/">
整合Eureka
在springboot的启动 项上使用 @EnableEurekaClient
使用默认的负载均衡算法
当我们不指定负载均衡算法的时候默认使用的是轮询算法
指定使用那个服务,name是服务的名称, configurtion表示加载那个类(一会说到,一般是自定义配置企业的负载均衡类)
@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MySelfRule.class)
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "consumer/dept/list")
public List<Dept> list(Dept dept) {
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
}
随机访问
过滤:
1. 多次出现故障的服务
2 . 并发连接数超过阀值的服务
3. 根据剩余的服务列表按照最开始默认的轮询机制进行访问
当遇到服务失败的时候他会主动的跳过,并且可以制定时间重新检查服务是否已经恢复
平均响应时间计算权重
1. 响应越快服务权重越大,选中率越高
2. 建议,最开始的时候先别使用平均响应时间计算权重,因为这个时候统计信息可能不够全面,所以一般在最开始的时候可以使用轮询机制,等到信息你全面的时候可以使用weightResponseTimeRule
过滤被多次访问并且故障的服务, 然后选择一个并发量下的服务
默认规则, 复合判断server所在区域性能和server的可用性选择服务器
1 基本AbstractLoadBalancerRule (其实把源码拿过来就行了)
源码地址
https://github.com/Netflix/ribbon
自定义的配置的业务是假设我们让3台服务分别访问5次,然后切换下一台服务
//total ===5 一会才可以替换机器
// index = 3 表示服务只有3台
// total ===5的时候我们至为0,然后index=3
private int total = 0;
private int currentIndex = 0;
/**
* Randomly choose from all living servers
*/
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();
int serverCount = allList.size();
if (serverCount == 0) {
/*
* No servers. End regardless of pass, because subsequent passes
* only get more restrictive.
*/
return null;
}
//修改的内容
if(total<5){
server = upList.get(currentIndex);
total++;
}else {
total = 0;
currentIndex ++;
if (currentIndex>=upList.size()){
currentIndex=0;
}
}
// int index = chooseRandomInt(serverCount); 随机获取索引值index
// server = upList.get(index); 得到服务器实例
if (server == null) {
/*
* The only time this should happen is if the server list were
* somehow trimmed. This is a transient condition. Retry after
* yielding.
*/
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Shouldn't actually happen.. but must be transient or a bug.
server = null;
Thread.yield();
}
return server;
}
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
2 . 把刚刚自定义的配置加载到spring容器里面
/**
* @Author: judy
* @Description: 自定义Ribbon
* @Date: Created in 11:50 2019/3/27
*/
@Configuration
public class MySelfRule {
@Bean
public IRule myRule() {
return new RandomRule_ZY();
}
}
注意刚刚的那两个方法不能放在服务的启动项里面,也就是在springbootapplication下面, 官方已经明确指出,原因是因为@ComponentScan,否则不会认为你是自己自定义的ribbon
@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MySelfRule.class)
LoadBalancerClient
当她在初始化的时候会去服务注册列表,并且通过10s一次向EurekaClient发送ping命令, 判断服务是否可以用
IRule
如果有了服务注册列表她会通过IRule 进行负载均衡
1loadBalancerClient------>IloadBalancer---->IRule,Ping ---->EurekaClient