Spring Cloud R巾bon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 NetflixRibbon 实现。 通过 Spring Cloud 的封装, 可以让我们轻松地将面向服务的 REST 模板请求自动转换成客户端负载均衡的服务调用
我们通常所说的负载均衡都指的是服务端负载均衡, 其中分为硬件负载均衡和软件负载均衡。 硬件负载均衡主要通过在服务器节点之间安装专门用于负载均衡的设备,比如 F5 等;而软件负载均衡则是通过在服务器上安装一些具有均衡负载功能或模块的软件来完成请求分发工作, 比如Nginx 等
硬件负载均衡的设备或是软件负载均衡的软件模块都会维护一个下挂可用的服务端清单,通过心跳检测来剔除故障的服务端节点以保证清单中都是可以正常访问的服务端节点。当客户端发送请求到负载均衡设备的时候, 该设备按某种算法(比如线性轮询、 按权重负载、 按流量负载等)从维护的可用服务端清单中取出一台服务端的地址, 然后进行转发
客户端负载均衡和服务端负载均衡最大的不同点在千上面所提到的服务清单所存储的位置。 在客户端负载均衡中, 所有客户端节点都维护着自己要访问的服务端清单, 而这些服务端的清单来自于服务注册中心。我们在微服务架构中使用客户端负载均衡调用非常简单, 只需要如下两步:
Spring Cloud中定义了LoadBalancerClient作为负载均衡器的通用接口, 并且针对R巾bon实现了贮bbonLoadBalancerClien七, 但是它在具体实现客户端负载均衡时,是通过Ribbon的ILoadBalancer接口实现的
AbstractLoadBalancer是ILoadBalancer接口的抽象实现。在该抽象类中定义了一个关于服务实例的分组枚举类 ServerGroup, 它包含以下三种不同类型:
另外, 还实现了一 个 chooseServer () 函数, 该函数通过调用接口中的chooseServer (Object key)实现, 其中参数key为 null, 表示在选择具体服务实例时忽略key的条件判断
public abstract class AbstractLoadBalancer implements ILoadBalancer { public enum ServerGroup{ ALL, STATUS UP, STATUS NOT UP
} public Server chooseServer() { return chooseServer(null);
}
//定义了根据分组类型来获取不同的服务实例的列表 public abstract Lis七<Server> getServerLis七(ServerGroup serverGroup);
//定义了获取 LoadBalancerStats 对象的方法,LoadBalancerStats 对象被用来存储负载均衡器中各个服务实例当前的属性和统计信息 public abstract LoadBalancerStats getLoadBalancerStats(}; }
BaseLoadBalancer 类是和bbon 负载均衡器的基础实现类,在该类中定义了很多关于负载均衡器相关的基础内容:
DynamicServerListLoadBalancer 类继承于 BaseLoadBalancer 类, 它是对基础负载均衡器的扩展。 在该负载均衡器中, 实现了服务实例清单在运行期的动态更新能力;同时, 它还具备了对服务实例清单的过滤功能, 也就是说, 我们可以通过过滤器来选择性地获取一批服务实例清单
由于Ribbon中定义的每一个接口都有多种不同的策略实现,同时这些接口之间又有 一定的依赖关系,这使得第一次使用伈bbon的开发者很难上手,不知道如何选择具体的实现策略以及如何组织它们 的关系。 Spring Cloud凡bbon中的自动化配置恰恰 能够解决这样的
痛点,在引入Spring Cloud Ribbon的 依赖之后, 就能够自动化构建下面这些接口的实现:
对千Ribbon的参数 配置通常有两种方式: 全局配置以及指定客户端配置
当在Spring Cloud的应用中同时引入Spring Cloud Ribbon和Spring Cloud Eureka依赖时,会触发Eureka中 实现的对Ribbon的自动化配置。这时 ServerList的维护机制实现将被com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList的实例所覆盖, 该实现会将服务清单列表交给Eureka的服务治理机制来进行维护;IPing的实现将被com.netflix.niws.loadbalancer.NIWSDiscoveryPing的实例所覆盖, 该实现也将实例检查的任务交给了 服务治理框架来进行维护。 默认情况下, 用 于获取实例请求的ServerLis七接口实现将采用Spring Cloud Eureka中封装的org.springframework.cloud.netf巨x.ribbon.eureka.DomainExtractingServerLis七,其目的是为了让实例维护策略更加通用, 所以将使用物理元数据来进行负载均衡, 而不是使用原生的AWSAMI元数据
由于Spring Cloud Eureka实现的服务治理机制强调了CAP原理中的AP, 即可用性与可靠性,它与Zoo Keeper这类强调CP( 一致性、可靠性)的服务治理框架最大的区别就是,Eureka为了实现更高的服务可用性, 牺牲了一定的一致性, 在极端情况下它宁愿接受故障实例也不要丢掉 “ 健康” 实例, 比如, 当服务注册中心的网络发生故障断开时, 由于所有的服务实例无法维持续约心跳, 在强调AP的服务治理中将会把所有服务实例都剔除掉,而Eureka则会因为超过85%的实例丢失心跳而会触发保护机制,注册中心将会保留此时的所有节点, 以实现服务间依然可以进行互相调用的场景, 即使其中有部分故障节点, 但这样做可以继续保障大多数的服务正常消费
以hello-service服务的调用为例, 可以在配置文件中增加如下内容:
1 spring.cloud.loadbalancer.retry.enabled=true 2 hystrix.command.default.execution.isolation.thread.timeoutinMilliseconds=lOOOO 3 hello-service.ribbon.ConnectTimeout=250 4 hello-service.ribbon.ReadTimeout=lOOO 5 hello-service.ribbon.OkToRetryOnAllOperations=true 6 hello-service.ribbon.MaxAutoRe七riesNex七Server=2 7 hello-service.ribbon.MaxAutoRetries=l
hystrix.command.default.execution.isolation. thread.timeoutInMilliseconds: 断路器的超时时间需要大于Ribbon的超时时间, 不然不会触发重试
hello-service.ribbon.MaxAutoRetriesNextServer: 切换实例的重试次数
hello-service.ribbon.MaxAutoRetries: 对当前实例的重试次数
根据如上配置, 当访问到故障请求的时候, 它会再尝试访问 一次当前实例(次数由MaxAutoRetries配置), 如果不行, 就换 一个实例进行访问, 如果还是不行,再换 一次实例访问(更换次数由MaxAutoRe红iesNextServer配置),如果依然不行, 返回失败信息
第四章 客户端负载均衡:Spring Cloud Ribbon
原文:https://www.cnblogs.com/hzzjj/p/10226759.html