1.什么是负载均衡
当多个相同的服务的服务提供者被注册到注册中心后,服务消费者去调用服务,考虑到当多个消费者会去访问同一服务提供者的服务,这样会造成个别提供者没用访问量,而有的提供者都快挤爆服务器了,那么他的解决方案就是负载均衡,他会让消费者通过负载均衡算法均衡的去访问这些服务提供者;这样就有效的提高了服务的吞吐量(访问量),提高了网络的灵活性和高可用性
2.负载均衡的作用
它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
3.Ribbon是什么
Spring Cloud Ribbon时基于Netfix Ribbon实现的一套客户端负载均衡工具
简单的说Ribbon是Netfix发布的开源的项目,主要提供在客户端的软件负载均衡算法,Ribbon的客户端组件提供了一系列完整的配置如:连接超时,重试等,
Ribbon自带的负载均衡算法有轮询(默认),随机。同时也可以自定义负载均衡算法(本质通过ribbon内部的规则将原有的算法覆盖实现的)
4.实现Ribbon
导入相关依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.6.RELEASE</version> </dependency>
(1)使用Ribbon自带的负载均衡算法,实现轮询/随机
(2)自定义负载均衡
注意:(官方)自定义的负载均衡算法不能写在主启动类的同级包下
自定义算法
package com.king.myrule; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import org.springframework.context.annotation.Bean; import java.util.List; import java.util.concurrent.ThreadLocalRandom; //自定义负载均衡算法 public class KingRandomRule extends AbstractLoadBalancerRule { /**每个服务访问5次换下一个服务 * 思路:total=0 默认0 如果=5,指针指向下一个节点 * index=0 默认0 如果=5,index+1, * */ private int total = 0;//被调用的次数 private int currentIndex = 0;//当前是谁在提供服务 public KingRandomRule() { } /* @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})*/ 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<Server> upList = lb.getReachableServers();//获得活着的服务 List<Server> allList = lb.getAllServers();//获得全部服务 int serverCount = allList.size(); if (serverCount == 0) { return null; } /** 随机调用源码 * int index = this.chooseRandomInt(serverCount);//生成区间,随机数 server = (Server)upList.get(index);//从活着的服务随机获取一个 */ if (total<5){ server = upList.get(currentIndex); total++; } else{ total = 0; currentIndex++; if (currentIndex>=upList.size()){ currentIndex = 0; } server = upList.get(currentIndex); } 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) { } }
将自定以算法注册进bean
//自定义的负载均衡算法在这里放到ioc容器里 //通过返回实例化自定以对象方式注册bean @Configuration public class KingRule { @Bean public IRule myRule(){ return new KingRandomRule(); } }