Spring cloud 之 LoadBalancer 篇
一. 概述
在微服务架构之负载均衡启动到承上启下的作用,按照指定的分发规则将流量分发到各个节点上,从而在一定程度上提高各个服务的运行效率。
负载均衡是基于提供了服务器列表中按照指定的算法(规则)去选出一个服务节点进行分发。目前市场上的负载算法(参考 nginx 的负载算法、现有的 spring cloud 的算法,以及 LVS 的负载算法),分类归纳如下:
请求报文算法,是基于请求报文内容维度进行负载策略。如用户 ID、请求 ID 等不同维度的请求报文内容;
IP 算法,根据服务器 IP 这个维度进行的负载策略。
随机
轮询
IP 哈希
权重算法,也叫加权方式。市场上常说的灰度发布,基本上都是基于权重算法,来达到平滑过渡的发布方式。
粘性连接,即第一次连接的目标 IP,后续的请求都分发到这个 IP 地址上。
基于请求路径进行负载策略
TCP 算法,根据网络层面上的指标进行的负载策略,如连接数,响应时间,backlog 等维度。
最少连接,即分发到连接数最少的服务节点上。这里有两个维度,一个是以客户端的角度,客户端连接各个服务器的连接数;另外一个是以服务端的角度,服务端提供的连接数。
最小延迟时间,即服务器处理请求的最短响应时间。客户端会采集各个服务节点的响应时间,从而从中选出响应时间最短的服务节点进行分发;
积压队列,当服务节点没有可用连接时,请求会暂时保存到 backlog 指定数量的集合中,待服务器处理完当前请求后,再去从积压队列中消费请求;这个在微服务中,基本是用不到的;因为在用户态中是拿不到这个指标的,只有内核态中拿到;所以这个可以不用考虑
OS 算法,通过采集服务器的各项指标从而进行的负载策略,如 CPU,内存,IO 等。这个目前没有开源的算法可以进行参考的,知道有这方面的策略即可。
当然里面还有组合的,如加权最少连接等。
spring cloud 的负载交互,基于注册中心交互而梳理的简单流程图如下:
二. Spring Cloud 负载
本节是基于 Spring Cloud 3.x 的源码进行解读的;基于上面的交互图再次细分一下,流程图一下:
基于 Resttemplate 发送请求的交互图,这里面涉及到了 Spring cloud commons 包中对负载相关的组件,如图所示:
基于 WebClient 发送请求的交互图,跟 Resttemplate 的交互图差不多,只是代码呈现方式不一样而已;可以查看 LoadBalancedExchangeFilterFunction 这个接口对应的实现类的过滤细节。
涉及到相关组件,将逐个讲解。
2.1 ***RequestTransformer
将 request 请求进行转换,通过这个接口,我们可以对 request 进行串改。具体细节可以通过查看其实现类。
基于 Resttemplate 使用的是 LoadBalancerRequestTransformer 接口,而 WebClient 使用的是 LoadBalancerClientRequestTransformer。
2.2 LoadBalancerClient
负载均衡客户端,该接口主要是做协调工作。
注意的是,WebClient 并没有使用该接口;
2.3 ReactiveLoadBalancer.Factory
用来创建负载均衡器的工厂类,该实现类是 LoadBalancerClientFactory,其实现原理是复用 spring 容器的形式来做的;所以,我们可以灵活的创建不同的负载均衡器,以及对不同的添加不同的定制内容。
2.3.1 LoadBalancerProperties
负载均衡器对应的相关配置信息,主要是心跳检测,以及重试机制,sticky 机制。
2.3.2 @LoadBalancerClient
该注解自定义每个目标服务对应的负载均衡器的配置信息;最终封装成 LoadBalancerClientSpecification 实例注入到 spring 容器内。
2.3.3 ReactorServiceInstanceLoadBalancer
负载均衡器。在 spring cloud common 有提供了两种实现方式,如随机、轮询等。
我们可以通过实现该接口去定制我们的负载均衡器,同时可以通过 @LoadBalancerClient 来指定不同目标服务的对应的负载策略器。
其原理是通过 spring 容器去扫描 @LoadBalancerClient 指定的配置类,将该类中相关的负载均衡器相关实例注入到该目标服务的所对应的 spring 容器。
2.4 ReactiveLoadBalancer
具体的负载均衡器,其主要的工作的筛选出目标 IP。
2.5 ServiceInstanceListSupplier
其接口主要是返回了目标 IP 列表;如果使用了注册服务发现,例如 eureka 的,则实现类 DiscoveryClientServiceInstanceListSupplier。
然而其不单单只是返回目标 IP 列表,同时也包含了额外的过滤规则以及额外的特性。
CachingServiceInstanceListSupplier 其缓存目标 IP 列表
HintBasedServiceInstanceListSupplier 可以根据 hint 提示来筛选目标 IP 列表
RequestBasedStickySessionServiceInstanceListSupplier 粘性
三. 实践
对 spring cloud LoadBalancer 介绍了大体的组件以及交互过程。需要实践,才可以进一步掌握的。
1. Resttemplate 负载入门
第一步:使用带有负载均衡的 resttemplate 实例
第二步:正常调用 Resttemplate 发送请求
默认情况下使用的是轮询负载均衡器。
2. 进阶-定制加权负载
第一步: 往 spring 容器注入加权负载均衡器
第二步:正常调用 Resttemplate 发送请求
3. 高阶
通过 Hint 方式,以及 @LoadBalancerClient 注解去定制各个目标服务的负载均衡器等。这里就不再过多阐述。感兴趣的自行通过代码去了解其原理,并实现定制化的负载均衡器
版权声明: 本文为 InfoQ 作者【邱学喆】的原创文章。
原文链接:【http://xie.infoq.cn/article/2f71dcf2e202bf324f19ee195】。文章转载请联系作者。
评论