源码分析Dubbo Invoker概述—-服务发现、集群、负载均衡、路由体系

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 源码分析Dubbo Invoker概述—-服务发现、集群、负载均衡、路由体系


前言

Invoker,负载网络调用组件,底层依懒与网络通信,Invoker主要负责服务调用,自然与路由(比如集群)等功能息息相关,本节先从整体上把控一下Dubbo服务调用体系,服务发现、集群、负载均衡、路由机制等整个知识体系,梳理整理Dubbo Invoker整个类图如下:

源码分析Dubbo Invoker概述----服务发现、集群、负载均衡、路由体系

分析

主要有如下接口群 

**1、Invocation(调用上下文环境) **
**1.1 Invocation: **
1)String getMethodName() 获取调用方法名。 
2)Class ? [] getParameterTypes() 获取被调用方法的参数列表(参数类型) 
3)Object[] getArguments() 获取被调用方法的参数值数组。 
4)Map String, String getAttachments() 获取附加属性。 
5)String getAttachment(String key) 根据key获取附加属性值。 
6)String getAttachment(String key, String defaultValue) 根据key获取附加属性,如果不存在,取默认值。 
7)Invoker ? getInvoker() 获取当前的invoker。 

1.2 RpcInvocation rpc服务调用实现类
Invocation执行调用上下文环境,就是用一个Bean存储当前调用方法的参数,其本质就是一个普通的Bean而已。
**1.3 MockInvocation **
用于mock单元测试用。 
**1.4 DecodeableRpcInvocation 带解码功能的rpc调用上下文 **
该实现主要能从RPC服务调用请求中解析二进制流(二进制包)得到RPC服务调用上下文(方法调用元数据)。

**2、Invoker 服务调用器,Dubbo中调用服务的抽象。 **
Invoer的抽象接口,继承自com.alibaba.dubbo.common.Node接口 
Node: 
URL getUrl(); 获取URL,在dubbo中,注册中心、服务提供者、服务消费者、监控中心等都使用URL描述。 
boolean isAvailable() :判断是否可用。 
void destroy() :资源销毁。 
Invoker: 
Class getInterface() :获取服务提供者的接口。 
Result invoke(Invocation invocation) throws RpcException :调用服务,返回调用结果。 
**2.1 AbstractInvoker Invoker默认实现(模板类) **
该方法主要实现public Result invoke(Invocation inv) throws RpcException,定义执行invoker的基础流程(模板),然后根据不同的实现子类(不同的协议)执行各自个性化的执行任务。其抽象方法:protected abstract Result doInvoke(Invocation invocation) throws Throwable,具体实现将在后文中分析。 
2.1.1 DubboInvoker dubbo协议调用器具体实现。 
2.1.2 InjvmInvoker injvm协议调用其具体实现(本地协议) 
**2.2 AbstractClusterInvoker 集群模式调用模板类 **
该类为Dubbo集群模式的调用模板类,主题解决一个服务服务有多个服务提供者,此时消息消费端在调用服务时如何选择具体的服务提供者。该类需要组织多个服务提供者,并按照指定算法选择一服务提供者进行调用。 
2.2.1 AvailableClusterInvoker 
通过 dubbo:service cluster = “available” …/ 或 dubbo:reference cluster=”available” …/ 
集群策略:总是选择第一个可用的服务提供者。 
2.2.2 BroadcastClusterInvoker 
通过 dubbo:service cluster = “broadcast” …/ 或 dubbo:reference cluster=”broadcast” …/ 
集群策略:广播模式,向所有服务提供者都发送请求,任何一个调用失败,则认为失败。 
2.2.3 FailbackClusterInvoker 
通过 dubbo:service cluster = “failback” …/ 或 dubbo:reference cluster=”failback” …/ 
集群策略:服务调用失败后,定时重试,重试次数无线次,重试频率:5s。并不会切换服务提供者。 
2.2.4 FailfastClusterInvoker 
通过 dubbo:service cluster = “failfast” …/ 或 dubbo:reference cluster=”failfast” …/ 
集群策略:服务调用后,快速失败,直接抛出异常,并不重试,也不受retries参数的制约,适合新增、修改类操作。 
2.2.5 FailoverClusterInvoker 
通过 dubbo:service cluster = “failover” …/ 或 dubbo:reference cluster=”failover” …/ 
集群策略:服务调用后,如果出现失败,则重试其他服务提供者,默认重试2次,总共执行3次,重试次数由retries配置,dubbo集群默认方式。 
2.2.6 FailsafeClusterInvoker 
通过 dubbo:service cluster = “failsafe” …/ 或 dubbo:reference cluster=”failsafe” …/ 
集群策略:服务调用后,只打印错误日志,然后直接返回。 
2.2.7 ForkingClusterInvoker 
通过 dubbo:service cluster = “forking” …/ 或 dubbo:reference cluster=”forking” …/ 
集群策略:并发调用多个服务提供者,取第一个返回的结果。可以通过forks设置并发调用的服务台提供者个数。 
更多的集群策略,可以参考/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.Cluster文件: 

源码分析Dubbo Invoker概述----服务发现、集群、负载均衡、路由体系

**3、LoadBalance 集群负载算法 **
当一个服务有多个服务提供者时,消费端在进行服务调用时选择服务服务提供者的负载均衡算法。 
LoadBalance定义的接口为: 
Invoker select(List Invoker invokers, URL url, Invocation invocation) throws RpcException; 
**3.1 ConsistentHashLoadBalance **
可以通过 dubbo:service loadbalance=”consistenthash” …/或 dubbo:service loadbalance = “consistenthash” …/ 
负载均衡算法:一致性Hash算法,在AbstractClusterInvoker中从多个服务提供者中选择一个服务提供者时被调用。 
**3.2 LeastActiveLoadBalance **
可以通过 dubbo:service loadbalance=”leastactive” …/或 dubbo:service loadbalance = “leastactive” …/ 
负载均衡算法:最小活跃调用。 
可以通过 dubbo:service loadbalance=”random” …/或 dubbo:service loadbalance = “random” …/ 
负载均衡算法:随机,如果weight(权重越大,机会越高) 
**3.3 RandomLoadBalance **
可以通过 dubbo:service loadbalance=”roundrobin” …/或 dubbo:service loadbalance = “roundrobin” …/ 
负载均衡算法:加权轮询算法。 

4、Directory(目录服务,Invoker的目录服务) 
该接口主要的作用是服务提供者的目录服务,管理多个服务提供者。 
**4.1 Directory **
1)Class getInterface() 获取该服务接口类别。 
2)List Invoker list(Invocation invocation) throws RpcException 根据调用上下文获取当前所有该服务的服务提供者。 
4.2 AbstractDirectory 目录服务实现的抽象列(模板类) 
**4.3 StaticDirectory 静态目录服务 **
所谓静态目录服务就是在创建StaticDirectory时指定一个服务提供者集合,则该目录服务实例在其生命周期中,只会返回这些服务提供者。 
4.4 RegistryDirectory 动态目录服务(基于注册中心) 
从注册中心动态获取发现服务提供,默认消息消费者并不会指定特定的服务提供者URL,所以会向注册中心订阅服务的服务提供者(监听注册中心providers目录),利用RegistryDirectory自动获取注册中心服务器列表。 

**5、Router 路由功能 **
根据消息消费者URL,结合路由表达式或JS引擎,从Directory中选择符合路由规则的Invoker,再执行负载均衡算法。 
**5.1 Router **
1)URL getUrl(); 获取消息消费者URL。 
2) List Invoker route(List Invoker invokers, URL url, Invocation invocation) throws RpcException 根据消息消费者URL,从invokers中筛选合适的Invokers。 
5.2 ConditionRouter 基于条件表达式的路由实现
5.3 ScriptRouter 基于JS引擎的路由实现

单个Invoker的实现,例如DubboInvoker、InJVMInvoker底层调用网络通道发送请求命令(oneway、同步、异步调用方式),其网络底层细节将在后续专门讲解网络实现篇章重点分析,接下来的篇章,主要从源码的角度剖析集群、负载均衡、动态路由目录服务(RegistryDirectory )的实现细节。

文/编辑  by  Justin

原创  by  丁威

源码分析Dubbo Invoker概述----服务发现、集群、负载均衡、路由体系

原文始发于微信公众号(Justin的后端书架):

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 源码分析Dubbo Invoker概述—-服务发现、集群、负载均衡、路由体系


 上一篇
源码分析Dubbo服务注册与发现机制 源码分析Dubbo服务注册与发现机制
前言 RegistryDirectory,基于注册中心的服务发现,本文将重点探讨Dubbo是如何实现服务的自动注册与发现。从上篇文章,得知在消息消费者在创建服务调用器(Invoker)【消费者在初始时】时需要根据不同的协议,例如dubbo、
2021-04-05
下一篇 
源码分析Dubbo服务提供者启动流程.续集 源码分析Dubbo服务提供者启动流程.续集
前言 本文继续上文Dubbo服务提供者启动流程,在上篇文章中详细梳理了从dubbo spring文件开始,Dubbo是如何加载配置文件,服务提供者dubbo:service标签服务暴露全流程,本节重点关注RegistryProtocol#e
2021-04-05