ITPub博客

首页 > 数据库 > 数据库开发技术 > 深度:一文搞懂Ribbon使用及内核原理剖析

深度:一文搞懂Ribbon使用及内核原理剖析

原创 数据库开发技术 作者:Fox666 时间:2020-12-03 16:43:52 0 删除 编辑


1.什么是Ribbon


Spring Cloud Ribbon是 基于Netflix Ribbon 实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。通过Load Balancer( LB )获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。

Ribbon也可以实现我们自己的负载均衡算法。


1.1 什么是客户端的负载均衡


进程内的LB,他是一个类库集成到消费端,通过消费端进行获取提供者的地址。

生活中: 类似与你去火车站排队进站(有三条通道),只要是正常人,都会排队到人少的队伍中去。


程序中: 我们消费端 能获取到服务提供者地址列表,然后根据某种策略去获取一个地址进行调用。

1.2 什么是服务端的负载均衡


生活中:类似与你去火车站排队进站的时候,有一个火车站的引导员告诉你说三号通道人少,你去三号通道排队。

程序中:就是你消费者调用的是ng的地址,由ng来选择 请求的转发(轮询 权重,ip_hash等)



2. 快速整合Ribbon

引入依赖

<dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring‐cloud‐starter‐netflix‐eureka‐client</artifactId> </dependency> <!‐‐添加ribbon的依赖, eureka client启动器已经依赖了ribbon,可以不配‐‐> <dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring‐cloud‐starter‐netflix‐ribbon</artifactId> </dependency>

添加@LoadBalanced注解

 @Bean @LoadBalanced public RestTemplate restTemplate() {  return new RestTemplate(); }

3.  Ribbon内核原理


3.1 Ribbon调用流程

3.2 Ribbon负载均衡策略



1. RandomRule:随机选择一个Server。

2. RetryRule:对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的server。

3. RoundRobinRule:轮询选择, 轮询index,选择index对应位置的Server。

4. AvailabilityFilteringRule:过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就是检查status里记录的各个Server的运行状态。

5. BestAvailableRule:选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过。

6. WeightedResponseTimeRule:根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低。

7. ZoneAvoidanceRule:复合判断Server所在区域的性能和Server的可用性选择Server。


3.2.1 修改默认负载均衡策略


@Configurationpublic class AppConfig {
  @Bean  @LoadBalanced  public RestTemplate restTemplate() {  return new RestTemplate();  }  @Bean  public IRule myRule() {  return new RandomRule();  } }

3.2.2 自定义负载均衡策略


1)自定义负载算法

 public class MyRandomRule extends AbstractLoadBalancerRule {
/** 总共被调用的次数,目前要求每台被调用5次 */ private int total = 0; /** 当前提供服务的机器号 */ private int currentIndex = 0;
public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } Server server = null;
while (server == null) { if (Thread.interrupted()) { return null; } //激活可用的服务 List<Server> upList = lb.getReachableServers(); //所有的服务 List<Server> allList = lb.getAllServers();
int serverCount = allList.size(); if (serverCount == 0) { return null; }
if (total < 5) { server = upList.get(currentIndex); total++; } else { total = 0; currentIndex++; if (currentIndex >= upList.size()) { currentIndex = 0; } } if (server == null) { Thread.yield(); continue; }
if (server.isAlive()) { return (server); }
// Shouldn't actually happen.. but must be transient or a bug. server = null; Thread.yield(); } return server; }
@Override public Server choose(Object key) { return choose(getLoadBalancer(), key); }
@Override public void initWithNiwsConfig(IClientConfig clientConfig) { } }

2)在SpringBoot主程序扫描的包外定义配置类

 @Configuration public class MySelfRule {  @Bean  public IRule myRule(){  return new MyRandomRule();  } }

注意:自定义的负载均衡策略不能写在@SpringbootApplication注解的@CompentScan扫描得到的地方,否则自定义的配置类就会被所有的 RibbonClients共享。

3)使用@RibbonClient指定负载均衡策略,在SpringBoot主程序添加 @RibbonClient 引入配置类

 @SpringBootApplication @RibbonClient(name = "service‐order",configuration = MySelfRule.class) public class ServiceMemberApplication {}



3.3 Ribbon相关接口


参考:org.springframework.cloud.netflix.ribbon.RibbonClientConfigurationIClientConfig:Ribbon的客户端配置,默认采用DefaultClientConfigImpl实现。

IRule:Ribbon的负载均衡策略,默认采用ZoneAvoidanceRule实现,该策略能够在多区域环境下选出最佳区域的实例进行访问。


IPing:Ribbon的实例检查策略,默认采用DummyPing实现,该检查策略是一个特殊的实现,实际上它并不会检查实例是否可用,而是始终返回true,默认认为所有服务实例都是可用的。


ServerList:服务实例清单的维护机制,默认采用ConfigurationBasedServerList实现。ServerListFilter:服务实例清单过滤机制,默认采ZonePreferenceServerListFilter,该策略能够优先过滤出与请求方处于同区域的服务实例。


ILoadBalancer:负载均衡器,默认采用ZoneAwareLoadBalancer实现,它具备了区域感知的能力。


修改配置:

# 使用<clientName>.ribbon.<key>=<value>的形式进行配置# 参考org.springframework.cloud.netflix.ribbon.PropertiesFactory# PingUrl: Get http://192.168.3.1:8010/# 指定IPingservice‐order.ribbon.NFLoadBalancerPingClassName=\com.netflix.loadbalancer.PingUrl# 指定IRuleservice‐order.ribbon.NFLoadBalancerRuleClassName=\com.netflix.loadbalancer.RandomRule



4 Ribbon内核源码图



(需要原图的朋友可以关注我的微信公众号:输入:Ribbon)


原文作者:Fox爱分享;如有侵权,请联系管理员删除。

下一篇: 没有了~
请登录后发表评论 登录
全部评论
图灵Fox老师,曾任互联网公司架构师,精通Java技术体系,具有十多年中间件研发和大型互联网项目架构经验,喜欢分享中间件、消息队列、搜索引擎、分布式存储、微服务以及云原生等技术

注册时间:2020-12-01

  • 博文量
    30
  • 访问量
    24100