客户端负载均衡:Spring Cloud Ribbon
一、负载均衡概念
负载均衡在系统架构中是一个非常重要,并且是不得不去实施的内容。因为负载均衡对系统的高可用性、
网络压力的缓解和处理能力的扩容的重要手段之一。通常所说的负载均衡指的是服务端负载均衡,分为
硬件负载均衡和软件负载均衡,服务端负载均衡架构方式:
负载均衡都会维护一个下挂可用的服务端清单,并通过心跳检测来剔除故障的服务端节点。
客户端负载均衡与服务端负载均衡最大的不同点在于服务清单的位置,在客户端负载均衡
中,所有的客户端节点都维护着自己要访问的服务端清单,这些清单都来自于服务注册中心。
二、快速入门
代码详情见:https://gitee.com/tangjiapi/RibbonDemon.git
三、Spring Cloud Ribbon 实战
1.Ribbon负载均衡策略与自定义配置
在Ribbon中有丰富的负载均衡策略可供选择:
策略类 命名 描述
RandomRule 随机策略 随机选择server
RoundRobinRule 轮询策略 按顺序选择server(默认策略)
RetryRule 重试策略 在一个配置时间段内当选择server不成功,则一直尝试选择一个可用的server
BestAvailableRule 最低并发策略 逐个考察server,如果server断路器打开,则忽略,在选择其中并发链接最低的server
AvailabilityFilterRule 可用过滤策略 过滤掉一直链接失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)
ResponseTimeWeightRule 响应时间加权策略 根据server的响应时间分配权重。响应时间越长,权重越低,被选择到的概率就越低
ZoneAvoidanceRule 区域权衡策略 综合判断server所在区域的性能和server的可用轮询选择server,并且判定一个AWS Zonede的运行性能是否可用,剔除不可用的Zone中的所有Server.
1)全局策略设置
@Configuration public class TestConfiguration { @Bean public IRule ribbonRule() { return new RandomRule(); } }
凡是通过ribbon的请求都会按照配置的规则进行。
2)基于注解的策略设置
/** * 声明,用于排除 * @author Tang Jiujia * @since 2019-03-26 */ public @interface AvoidScan { }
@Configuration @AvoidScan public class TestConfiguration { @Autowired IClientConfig config; @Bean public IRule ribbonRule(IClientConfig config) { return new RandomRule(); } }
@SpringBootApplication @EnableDiscoveryClient @RibbonClient(name = "client-a", configuration = TestConfiguration.class) //让Spring不去扫描@AvoidScan注解的类,因为我们的配置是对单个服务源生效, // 所以不能应用于全局,如果不排除会报错 @ComponentScan(excludeFilters = {@ComponentScan.Filter (type = FilterType.ANNOTATION, value = {AvoidScan.class})}) public class RibbonLoadbalancerApplication { public static void main(String[] args) { SpringApplication.run(RibbonLoadbalancerApplication.class, args); } /** * 用于负载均衡 * */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
3)基于配置文件的策略设置
client-a:
ribbon:
NFLoadBalanceRuleClassName: com.netflix.loadbalancer.RandomRule
2.Ribbon超时与重试
F版中的Ribbon重试机制是默认开启的,需要添加对于超时时间与重试策略的配置:
client-a: ribbon: ConnectTimeout: 30000 ReadTimeout: 30000 MaxAutoRetries: 1 #对第一次请求的服务的重试次数 MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量 OkToRetryOnAllOperations: true
3.Ribbon的饥饿加载
Ribbon在进行客户端负载均衡时并不是在启动时就加载上下文,而是在实际请求时才去
创建,因此这个特性往往会让我们第一次调用时显得疲软乏力,严重时会引起调用超时。
所有我们可以通过指定Ribbon客户端的名称来开启饥饿加载,即在启动的时候就加载所有
配置项的应用程序上下文。
ribbon:
eager-load:
enabled: true
clients: client-a, client-b, client-c
4.利用配置文件自定义Ribbon客户端
使用配置文件的优先级最高,高于注解和源码中的bean
5.Ribbon脱离Eureka使用
默认情况下,Ribbon客户端会从Eureka注册中心读取服务注册列表,来达到一种
动态的负载均衡。但如果Eureka是一个供很多人使用的公共注册中心,极可能产生
服务侵入性问题,所以就不要从Eureka读取服务列表了,而应该在Ribbon客户端自行指定
服务地址,让Ribbon脱离Eureka来使用。
首先,需要在Ribbon中禁用Eureka功能:
ribbon: eureka: enable: false
然后对源服务设定地址列表:
client: ribbon: listOfServers: http://localhost:7070, http://localhost:7071