Spring Cloud入门系列(六)——负载均衡之Ribbon
概述![在这里插入图片描述](https://img-blog.csdnimg.cn/d2e2c6651b474e6586b5befb6bf679ff.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBALmxheW1hbg==,size_20,color_FFFFFF,t_70,g_se,x_16)
负载均衡
集中式LB
进程内LB![在这里插入图片描述](https://img-blog.csdnimg.cn/2ffab017bf2144b78907c7d2528296b1.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBALmxheW1hbg==,size_20,color_FFFFFF,t_70,g_se,x_16)
架构说明
其实ribbon已经被Eureka整合进去了。
RestTemplate
Ribbon的负载策略
IRule是Ribbon实现负载均衡的顶层接口。
自定义策略
在80端口,新增com.banana.rule.MyRule文件
MyRule
package com.banana.rule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author layman
* @description: 自定义ribbon的负载均衡配置类
*/
@Configuration
public class MyRule {
@Bean
public IRule myRule(){
//切换为随机模式
return new RandomRule();
}
}
主启动类上添加 @RibbonClient
注解
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MyRule.class)
package com.banana.springcloud;
import com.banana.rule.MyRule;
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;
/**
* @author layman
* @date 2021/1/9
*/
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MyRule.class)
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args);
}
}
默认策略的源码解读
https://blog.csdn.net/single_0910/article/details/112696676
自定义轮询算法
80端口改造
package com.banana.springcloud.loadbalancer;
import org.springframework.cloud.client.ServiceInstance;
import java.util.List;
/**
* 自定义LoadBalancer
* @author layman
* @date 2021/1/16
*/
public interface MyLoadBalancer {
/**
* 获取可用的服务实例
* @param instances:服务列表
* @return 单个的服务
*/
ServiceInstance getInstance(List<ServiceInstance> instances);
}
package com.banana.springcloud.loadbalancer.impl;
import com.banana.springcloud.loadbalancer.MyLoadBalancer;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 自定义轮询策略
* @author layman
* @date 2021/1/16
*/
@Component
public class MyLoadBalancerImpl implements MyLoadBalancer {
private AtomicInteger nextServerCounter = new AtomicInteger(0);
public final int getAndIncrement(){
int current;
int next;
do{
current = nextServerCounter.get();
next = (current > Integer.MAX_VALUE ? 0 : current + 1);
}while(!this.nextServerCounter.compareAndSet(current,next));
System.out.println("--------次数next的值--------:"+next);
return next;
}
@Override
public ServiceInstance getInstance(List<ServiceInstance> instances) {
int index = getAndIncrement() % instances.size();
return instances.get(index);
}
}
80端口的OrderController
@Resource
private MyLoadBalancer myLoadBalancer;
@GetMapping("/LoadBalancer")
public String discovery(){
//获取对应名称的所有server数量
List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
if(instances ==null || instances.size() <=0){
return null;
}
ServiceInstance server = myLoadBalancer.getInstance(instances);
URI uri = server.getUri();
String object = restTemplate.getForObject(uri + "/payment/LoadBalancer", String.class);
return object;
}