我们首先看看Dubbo远程调用的执行时序图
首先进入的是dubbo-rpc模块
InvokerInvocationHandler
|
|
其中最后一行是重点
|
|
invoker 是定义的接口,它继承了Node接口,详解见微服务架构之Dubbo集群容错(3)。而这个invoker的实现是MockClusterInvoker类。
然后是dubbo-cluster模块
MockClusterInvoker
|
|
首先是检测是否配置了mock模式, mock模式参考微服务架构之Dubbo服务降级。我们这个流程没有配置mock模式,所以会执行 result = this.invoker.invoke(invocation),调用的就是AbstractClusterInvoker类的实现。
AbstractClusterInvoker
|
|
其中
|
|
是重点,它的实现来自AbstractDirectory类。
AbstractDirectory
|
|
其中
|
|
是重点,对于doList抽象方法目前有2种实现,RegistryDirectory和StaticDirectory。关于这些我们会在微服务架构之Dubbo集群容错(3)中讲解。下面展示的是常用的RegistryDirectory类的实现。
RegistryDirectory
|
|
然后将invokers返回,我们回到AbstractDirectory类,获得到invokers之后,就是路由了。
|
|
这个是重点,这个route接口有3个是实现,ConditionRouter,MockInvokersSelector,ScriptRouter ,详细见微服务架构之Dubbo集群容错(3)。MockInvokersSelector类在这里是关注重点。
MockInvokersSelector
|
|
一般的调用没有设置mock,会在getNormalInvokers方法中的hasMockProviders判断中就返回了。
好了,这个时候路由也结束了,过程回到AbstractClusterInvoker类。
|
|
根据官网的描述,在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。我们看一下继承AbstractClusterInvoker类的FailoverClusterInvoker。
FailoverClusterInvoker
|
|
首先获取调用方法的重试次数,然后进入for循环,重要的是
|
|
它在抽象类AbstractClusterInvoker中已经实现
|
|
我们发现首先是校验是否配置了sticky, sticky代表粘滞连接,粘滞连接⽤于有状态服务, 尽可能让客户端总是向同⼀提供者发起调⽤, 除⾮该提供者挂了, 再连另⼀台。粘滞连接将⾃动开启延迟连接, 以减少⻓连接数。配置如下:
|
|
然后最重要的是
|
|
|
|
其中重点是
|
|
包括在后面的reselect时候,也会用到loadbalance.select方法。其实现是AbstractLoadBalance抽象类。
AbstractLoadBalance
|
|
我们看到经过简单的处理之后,doSelect(invokers, url, invocation)变为重点,它是个抽象方法,有四种实现,分别是RoundRobinLoadBalance,RandomLoadBalance,LeastActiveLoadBalance,ConsistentHashLoadBalance。默认情况是 RandomLoadBalance。
RandomLoadBalance
|
|