1.作用:负载均衡会帮消费者在每次请求时选择一台机器,均匀的把请求分发到各个机器上。
2.使用方法
(1)添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
(2)创建RestTemplate实例,通过@LoadBalanced注解开启均衡负载能力,并选择使用的负载均衡策略。
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@Bean
public IRule muRule() {
// return new RoundRobinRule();//轮询
//return new WeightedResponseTimeRule();//响应时间作为选取权重的负载均衡策略,其含义就是,响应时间越短的服务被选中的可能性大,继承自RoundRobinRule类。
// return new RandomRule();// 随机
return new RibbonRule();//自定义策略
}
(3)Ribbon提供了很多负载均衡策略,例如轮询、随机等,在配置服务提供者地址后,可以将服务消费者请求均匀的分发。
1)简单轮询负载均衡(RoundRobin):以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。
2)随机负载均衡 (Random):随机选择状态为UP的服务提供
3)加权响应时间负载均衡 (WeightedResponseTime):根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。
4)区域感知轮询负载均衡(ZoneAvoidanceRule):复合判断server所在区域的性能和server的可用性选择server
(4)自定义负载均衡策略
public class RibbonRule extends AbstractLoadBalancerRule {
/**
* 总共被调用的次数,目前要求每台被调用2次
*/
private int total = 0;
/**
* 当前提供服务列表的索引
*/
private int currentIndex = 0;
@Override public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
/**
* 在choose方法中,自定义自己的规则,返回的Server就是具体选择出来的服务
* 自己的规则:按照轮询的规则,但是每个被轮询到的服务调用3次。
* @param o
* @return
*/
@Override public Server choose(Object o) {
// 获取负载均衡器lb
ILoadBalancer lb = getLoadBalancer();
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
// 获取可用服务列表
List<Server> upList = lb.getReachableServers();
System.out.println("可用服务列表:");
for(int i=0; i<upList.size();i++){
System.out.println(upList.get(i));
}
// 获取所有服务列表
List<Server> allList = lb.getAllServers();
System.out.println("所有服务列表:");
for(int i=0; i<allList.size();i++){
System.out.println(allList.get(i));
}
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
// 若调用次数小于2次,一直调用可用服务列表中索引为 currentIndex 的服务
if(total < 2)
{
server = upList.get(currentIndex);
System.out.println(currentIndex);
total++;
System.out.println(total);
} else {
// 到了2次之后,服务列表中的索引值++,表示下一个调用下一个服务
total = 0;
currentIndex++;
// 当索引大于可用服务列表的size时,要重新从头开始
currentIndex = currentIndex % upList.size();
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
server = null;
Thread.yield();
}
}
return server;
}
}
(5)服务注册及项目结构如图: