SpringCloud05-Ribbon

SpringCloud05-Ribbon

1.Ribbon

  1. Ribbon主要功能是提供客户端的软件负载均衡算法和服务调用。同时Ribbon会在客户端提供连接超时,重试等配置项。
  2. Ribbon源码地址。https://github.com/Netflix/ribbon
  3. 一般Ribbon+RestTemplate一起使用,Ribbon进行负载均衡,RestTemplate负载远程服务调用。

2.集中式LB和进程内LB

  1. 集中式LB就是在服务的消费方和提供方之间使用独立的LB设施(如F5、nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方。
  2. 进程内LB就是将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
  3. Ribbon属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

3.创建Ribbon客户端微服务cloud-eureka-consumer-ribbon-order80

  1. 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>
  1. yml和业务类不变。
  2. 配置类。
@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();
    }
}
  1. 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);
    }
}
  1. Ribbon+RestTemplate通过微服务名称访问服务的提供方。

4.Ribbon的工作流程

  1. 第一步,先选择Eureka Server ,优先选择在同一个区域内负载较少的Server。
  2. 第二步,根据用户指定的策略,在从Eureka Server取到的服务注册列表中选择一个地址。

5.Ribbon中的负载均衡算法

  1. RoundRobinRule,轮询。
  2. RandomRule,随机。
  3. RetryRule,先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试。
  4. WeightedResponseTimeRule,对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择。
  5. BestAvailableRule,会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
  6. AvailabilityFilteringRule 先过滤掉故障实例,再选择并发较小的实例。
  7. 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;
    }
}
posted @ 2021-10-07 19:53  行稳致远方  阅读(23)  评论(0)    收藏  举报