zoukankan      html  css  js  c++  java
  • SpringCloud(二)之我学 Ribbon

    1、负载均衡

      Ribbon 虽然不是显示的配置为一个子项目,但是无论是在 API 网关的转发请求,还是服务之间的调用 Feign ,都是通过 Ribbon 来做负载均衡的。

      负载均衡,主要是为了对系统的高可用、网络压力的缓解和处理能力扩容。

    2、客户端负载均衡

      所有客户端节点都维护自己要访问的服务端清单,这些清单主要来源于注册中心(例如 Eureka Server),并且也是用心跳机制去维护服务端清单的健康性。

      微服务中使用负载均衡只需要两步:

      1)、服务提供者只需要启动多个服务实例,注册到一个注册中心,或者多个相关联的注册中心。

      2)、服务消费者直接通过调用,被 @LoadBalanced 注解修饰过的 RestTemplate 来实现面向服务的接口调用。

    3、原理

      RestTemplate有四种不同的请求类型和多种参数类型的服务调用实现。

      GET(查) 、 POST(增) 、PUT(改) 、DELETE(删) 四种请求。

      常见的异服务调用: (仅举例 get 请求)

      restTemplate.getForEntity(url,User.class):传入url,拼接参数。返回的对象 getBody() 就能获取到异服务调用的结果集。

      restTemplate.getObejct():入参和返回值都类似 getForEntity() 方法,只是返回实例不需要再 getBody()。

      源码分析:

      @LoadBalanecd 注解是用来给 RestTemplate 做标记,以使用负载均衡的客户端来配置它。(LoadBalancerClient)

      在 LoadBalancerClient 接口中的参数的定义:

      ServiceInstance choose(String serviceId):根据传入的服务名 serviceId,从负载均衡器中挑选一个对应服务的实例。

      T execute(String serviceId,LoadBalancerRequest request) throws IOException:使用从负载均衡器中挑选出的服务实例来执行请求内容。

      URI reconstructURI(ServiceInstance instance,URI original):为系统构建(返回)一个合适的 host:port 形式的URI。

      Ribbon 实现负载均衡自动化配置,需要满足以下两个条件:

      @ConditionalOnClass(RestTemplate.class):RestTemplate 类必须存在于当前工程的环境中。

      @ConditionalOnBean(LoadBalancerClient.class):在 Spring 的 Bean 工程中必须有 LoadBalancerClient 的实现 Bean。

      通过 LoadBalancerInterceptor 拦截器将 RestTemplate 变成客户端负载均衡。

      实现原理:被@LoadBalanced 注解修饰的 RestTemplate 对象向外发起 HTTP 请求时,会被 LoadBalancerIntercepetor 类的 intercept 函数拦截。在使用RestTemplate 时采用了服务名作为host,所以直接从 HttpRequest 的URI对象中通过 getHost() 拿到服务名,调用 execute 函数去根据服务名来选择 实例 并发起实际的请求。(实例是IP地址)

    4、负载均衡策略

      顶层为 IRule 规则接口,一个 AbstractLoadBalancerRule 继承了 IRule 接口,并且有一系列的实现规则。

      RandomRule:根据一个随机数,去获取可用实例列表,用随机数作为下标获取一个可用服务实例。

      RoundRobinRule:线性轮询方式依次选择每个服务实例。

      RetryRule:重试机制的实例选择功能。内部默认使用了 RoundRobinRule 实例。设定一个时间阈值,尝试时间超过阈值就返回 null。

      WeightedResponseTimeRule:对 RoundRobinRule 策略的扩展,根绝实例的运行情况,来计算权重来挑选实例,达到更优的分配效果。其中三个核心内容:

      1)、定时任务,默认30秒执行一次,为每个服务实例计算权重。

      2)、权重计算:计算每个实例实例平均响应时间,总平均响应时间,获取每个实例的权重区间。例如A、B、C、D 平均响应时间10,40,80,100,总230。计算A=230-10=[0,220],B=220+230-40=(220,410],C=(410,560],D=(560,690]。

      结论是平均响应时间越短,权重区间宽度越大,被选中的机会越大。

      3)、实例选择

      ZoneAvoidanceRule:选择区域策略,过滤实例,得到可用实例。(先过滤清单,再轮询选择)

      调用顺序(选择服务器逻辑): loadBalancerClient ---> ILoadBalancer(ZoneAwareLoadBalancer) 选择区域---> IRule (ZoneAvoidanceRule) 根据算法,选择具体服务实例。

      自己实现一个选择服务实例的负载方法:

     

    5、配置详解

      与 Eureka 结合:Eureka 会为架构维护所有服务的实例清单。由于 Ribbon 默认实现了区域亲和策略,可以通过 Eureka 实例的元数据配置来实现区域化的实例配置方案。比如将不同机房的实例配置成不同的区域值,作为跨区域的容错机制实现。

      实现也很简单,在服务实例的元数据中增加 zone 参数来指定自己所在的区域,例如:

      eureka.instance.metadataMap.zone=chengdu. (配置文件)

      @Bean (main 方法里)

      @LoadBalanced

      RestTemplate restTemplate() {

        return new RestTemplate();

      }

      在调用类里注入 RestTemplate 类,并且

      restTemplate.getForEntity("URL",String.class).getBody();

    6、重试机制

      Eureka 的服务治理机制强调了 CAP 原理的 AP,可用性和可靠性(C 一致性)。

      Eureka 为了实现更高的服务可用性,牺牲了一定的一致性。例如 Eureka 会因为超过85% 的实例丢失心跳而出发保护机制,注册中心会保留此时的所有节点。(极端情况接受故障也不丢掉“健康”实例)

      为了增强对服务故障实例的容错,所以加入了重试机制。通过简单的配置,那些通过 RestTemplate 实现的服务访问,就会自动根据配置来实现重试策略。

       

      重试次数,就是访问到故障请求,再尝试访问同一个实例,如果不行,就换一个实例访问。

      这两个重试由最后两个参数决定。

  • 相关阅读:
    centos7 安装jmeter5.1
    centos7 安装jdk1.8
    es6学习笔记(一)环境搭建
    Django-filter报错:__init__() got an unexpected keyword argument 'name'
    django fields lookup methods(lookup类型)
    django笔记-model
    Git-简单使用
    jenkins-master-slave节点配置总结
    Git-简单使用
    MySQL explain详解
  • 原文地址:https://www.cnblogs.com/AlmostWasteTime/p/11039392.html
Copyright © 2011-2022 走看看