SpringCloud05-Ribbon
1.Ribbon
- Ribbon主要功能是提供客户端的软件负载均衡算法和服务调用。同时Ribbon会在客户端提供连接超时,重试等配置项。
- Ribbon源码地址。https://github.com/Netflix/ribbon。
- 一般Ribbon+RestTemplate一起使用,Ribbon进行负载均衡,RestTemplate负载远程服务调用。
2.集中式LB和进程内LB
- 集中式LB就是在服务的消费方和提供方之间使用独立的LB设施(如F5、nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方。
- 进程内LB就是将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
- Ribbon属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。
3.创建Ribbon客户端微服务cloud-eureka-consumer-ribbon-order80
- pom.yml
<!-- spring-cloud-starter-netflix-eureka-client 2020.0.3版本的依赖中不包含ribbon,
而是使用 spring-cloud-starter-loadbalancer,所以使用Ribbon需要导入Ribbon的依赖。-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
- yml和业务类不变。
- 配置类。
@Configuration
public class RuleConfig {
/**
* 官方使用说明Ribbon的自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,
* 否则自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。
* 客户端使用轮训算法进行负载均衡。
* @return
*/
@Bean
public IRule rule() {
return new RoundRobinRule();
}
}
@Configuration
public class ApplicationContextConfig {
@LoadBalanced
@Bean("restTemplate")
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
- Main
@EnableEurekaClient
@SpringBootApplication
@RibbonClient(name = "cloud-provider-payment", configuration = RuleConfig.class)
public class CloudEurekaConsumerOrder80Main {
public static void main(String[] args) {
SpringApplication.run(CloudEurekaConsumerOrder80Main.class, args);
}
}
- Ribbon+RestTemplate通过微服务名称访问服务的提供方。
4.Ribbon的工作流程
- 第一步,先选择Eureka Server ,优先选择在同一个区域内负载较少的Server。
- 第二步,根据用户指定的策略,在从Eureka Server取到的服务注册列表中选择一个地址。
5.Ribbon中的负载均衡算法
- RoundRobinRule,轮询。
- RandomRule,随机。
- RetryRule,先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试。
- WeightedResponseTimeRule,对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择。
- BestAvailableRule,会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
- AvailabilityFilteringRule 先过滤掉故障实例,再选择并发较小的实例。
- ZoneAvoidanceRule 默认规则,复合判断Server所在区域的性能和Server的可用性选择服务器。
6.手动实现轮训负载均衡算法
public interface ILoadBalance {
ServiceInstance getInstance(List<ServiceInstance> serviceInstances);
}
@Component
public class LoadBalanceImpl implements ILoadBalance {
// 原子自增
private AtomicInteger counter;
public LoadBalanceImpl() {
counter = new AtomicInteger(0);
}
@Override
public ServiceInstance getInstance(List<ServiceInstance> serviceInstances) {
// 获取当前服务的调用次数,加1后,取模服务器数量,得到本次访问的服务器下标
int next = getAndIncrement() % serviceInstances.size();
if (CollectionUtil.isEmpty(serviceInstances)) {
return null;
}
return serviceInstances.get(next);
}
private int getAndIncrement() {
int current;
int next;
// CAS 操作,不成功,继续使用循环更新
do {
current = counter.get();
next = current >= Integer.MAX_VALUE ? 0 : current + 1;
}while (!counter.compareAndSet(current, next));
return next;
}
}