开发者社区> luyiisme> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Ribbon 2 核心设计和原理分析

简介: 原文发布在个人博客 Ribbon, Netflix 公司开源的用于进程通信场景的经过实战检验的客户端项目。它提供了远程调用的负载均衡,网络状态检查和容错等功能。Ribbon 基于软件的负载均衡方式与目标集群中的机器进行通信。
+关注继续查看

原文发布在个人博客

Ribbon, Netflix 公司开源的用于进程通信场景的经过实战检验的客户端项目。它提供了远程调用的负载均衡,网络状态检查和容错等功能。Ribbon 基于软件的负载均衡方式与目标集群中的机器进行通信。这里忽略状态统计部分,健康检查的逻辑部分,重点分析负载均衡部分。
下面是个典型的使用方式开始,先指定一些目标服务器地址,

//sample-client.ribbon.listOfServers=www.taobao.com:80,www.baidu.com:80,www.sina.com:80

然后借助ribbon 封装的 httpClient 来发送请求(访问站点首页),循环20次是希望打印出负载均衡的效果。

...
RestClient client = (RestClient) ClientFactory.getNamedClient("sample-client");  
HttpRequest request = HttpRequest.newBuilder().setUri(new URI("/")).build();
for (int i = 0; i < 20; i++)  {
  HttpResponse response = client.executeWithLoadBalancer(request);
  System.out.println("Status code for " + response.getRequestedURI() + "  :" + response.getStatus());
}

下面按 Ribbon 的主要模块进行设计分析,并在最后部分分析上述代码的效果。

Ribbon-core 模块

这一模块中,主要定义通用的调用抽象。ribbon 的 client 处理请求并返回响应。

public interface IClient<S extends ClientRequest, T extends IResponse> {
    public T execute(S request, IClientConfig requestConfig) throws Exception;
}

ClientRequest, 是独立于所以具体实现的通信协议的抽象。它主要包括:uri(远程资源的定位符),loadBalancerKey(Object类型,这是决定请求调用到目标服务器的关键信息),isRetriable; 当然它的具体实现类,可能还有请求headers,body等信息。

IResponse, 是服务端响应的抽象,主要包括: body(payload),isSuccess(响应状态的简化),响应headers,请求url;

VipAddress 术语,是一个地址的逻辑名,该逻辑名代表一系列目标服务器。比如“apple.bar:80”。

RetryHandler,用来决定哪些异常(比如:ConnectException,SocketTimeoutException)发生时要做重试,哪些异常(SocketException,SocketTimeoutException)发生时表示应该熔断掉(对应服务器)的调用,默认的是不重试。

Ribbon-loadbalancer 模块

负载均衡,宏观上效果是希望将请求的流量均衡(不是简单意义上的平均)的负载到提供服务的服务器之上。而对于每次请求而言,是通过计算拿到一个目标服务器地址的。

  • ILoadBalancer

ILoadBalancer, 负载均衡器的接口。它的核心方法是 public Server chooseServer(Object key); 每次请求发生时根据参数传入的 loadBalancerKey对象,决定出一个目标的服务器地址。Server 表示一个服务器(包括:主机地址,端口号以及一些元数据标识信息)。 那么服务均衡器应该需要有一批可供选择的目标服务集合吧,所以它还有个重要方法 addServers(List<Server> newServers),一般在启动阶段就要完成初始化地调用。

  • BaseLoadBalancer

BaseLoadBalancer(实现 ILoadBalancer),这里声明了一个基础lb,应该关联个 IRule(负载均衡的规则)默认是轮询规则:RoundRobinRule)。 它还默认支持一个Ping检查功能(可以帮忙我们定时检查目标服务器是否可通信)的定时任务,开发者可以在构造实例时明确指定 Iping(判断一个服务是否还是活的),IPingStrateg 默认是串行地检查策略,但如果目标服务地址过多,或者IPing执行过慢就不太合适。

IRule 路由规则,Rule 和 LoadBalancer 是一对一的相互关联关系,Rule 是具体的负责均衡策略。常见的规则包括: 轮询,随机,基于响应的延迟等; public Server choose(Object key)核心方法的输入输出基本一致,区别是 Rule 拿取目标 server list 是通过借助对应依赖的 LoadBalancer 拿到的。

  • DynamicServerListLoadBalancer

DynamicServerListLoadBalancer(继承 BaseLoadBalancer),事实上从启动后一直不变的 ServerList 场景一般不太多,尤其在微服务场景:服务挂了,扩容,缩容等都会需要对服务消费方的客户端的服务列表做出实时调整(通常借助服务发现产品:eureka,consul,zk...),DynamicServerListLoadBalancer 顾名思义就是针对该类场景的。要做到运行时实时更新,既要保证更新的实时可见,也要保证更新操作本身的同步。

ServerListUpdater,是动态服务列表的更新器。现实场景中一般有个专门提供发布和查询/订阅服务列表服务的角色,这里暂时简称为”远程注册表服务”。更新 ServerList 常见的有两种实现模式:push 或者 pull。 push 机制就是客户端保持对“远程注册表服务”观察就行,服务器发生变化时会,客户端就会及时得到通知。 还有一种 pull 机制,一般是频繁的发请求进行询问“远程注册表服务”是否有变化发生。这个一般建议基于常见的服务发现产品进行实现。

ServerListFilter,是DynamicServerListLoadBalancer的可选构造参数之一。作用是在发生 ServerList 更新时筛选过滤出符合条件的一个子集。 因为 ServerList 可能比较大,包含成百上千台机器地址,如果都尝试去调用,那么客户端的连接数就会非常多,这也会造成必要的消耗。

Ribbon-httpclient 模块

ribbon-loadbalancer 模块中有个 ClientFactory 静态工具类,可以生成和管理多个名字唯一的 IClient 具体实例。ClientFactory.getNamedClient("sample-client"); ,这里因为未特殊配置(指定具体的 IClient 的实现类),所以选择的是默认的Client实现类 com.netflix.niws.client.http.RestClient。

  • RestClient

RestClient,是 ribbon-httpclient 模块中针对 IClient 的具体实现,通过使用 Jesery Client (实际依赖 apacheHttpClient4 发送 http),同样 HttpRequest 实现 ClientRequest,而HttpResponse 实现了 ClientResponse。

client.executeWithLoadBalancer(request),是client的父类 AbstractLoadBalancerAwareClient 中定义的方法,最终是调用 LoadBalancerContext#getServerFromLoadBalancer(URI,loadBalancerKey)方法,该方法主要LB逻辑如下:

Server svc = lb.chooseServer(loadBalancerKey);
if (svc == null){
    throw new ClientException(ClientException.ErrorType.GENERAL,
            "Load balancer does not have available server for client: "
                    + clientName);
}

//... check host not null

logger.debug("{} using LB returned Server: {} for request {}", new Object[]{clientName, svc, original});
return svc;

著作权声明

首次发布于此,转载请保留以上链接

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Dubbo 工作原理
Dubbo 工作原理
22 0
数据分析入门系列教程-贝叶斯原理
如果你对当年学习的概率统计还有些印象的话,就一定会记得有个贝叶斯原理的东西,它是由英国数学家贝叶斯提出的。 贝叶斯原理和我们的生活是紧密相关的,比如说你身边的一个人经常去夜店,那么你会推测这个人多半是个浪子。虽然这不是绝对的,但是你依然可以根据和事物相关的一些事件来做出判断,如果事件发生的频次比较多,那么就证明该判断成立的可能性更大。
16 0
Netty实现原理分析
Netty实现原理分析
30 0
dubbo工作原理
dubbo工作原理
870 0
Dubbo Admin实现原理
开篇 这篇文章主要用于讲解清楚Dubbo Admin的监控数据的来源,如何通过zookeeper作为注册中心来获取实际运行中的数据进行服务治理。 这篇文章主要侧重于数据方面的获取包括consumers, configurators, routers, providers,具体如何进行服务治理后面文章会具体进行分析。
1285 0
决策树算法原理(下)
决策树算法原理(上)这篇里,我们讲到了决策树里ID3算法,和ID3算法的改进版C4.5算法。对于C4.5算法,我们也提到了它的不足,比如模型是用较为复杂的熵来度量,使用了相对较为复杂的多叉树,只能处理分类不能处理回归等。
784 0
DBoW2算法原理介绍
DBoW2算法原理介绍 本篇介绍DBoW2算法原理介绍,下篇介绍DBoW2的应用。 DBow2算法 DBow2是一种高效的回环检测算法,DBOW2算法的全称为Bags of binary words for fast place recognition in image sequence,使用的特征检测算法为Fast,描述子使用的是brief描述子,(TODO:和DBow的区
3357 0
+关注
luyiisme
https://luyiisme.github.io/
2
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载