@startuml
participant InvokerInvocationHandler
participant MockClusterInvoker
participant AbstractClusterInvoker
participant "MockInvokersSelector \nimplements Router" as MockInvokersSelector
'participant FailoverClusterInvoker

title 集群容错模式
autonumber 10 10 "<font color=red><b>[000]"
InvokerInvocationHandler ->   MockClusterInvoker:invoker.invoke(invocation)
MockClusterInvoker       ->   AbstractClusterInvoker:invoker.invoke(invocation)
activate AbstractClusterInvoker
AbstractClusterInvoker   ->   AbstractClusterInvoker:list(invocation)
AbstractClusterInvoker   ->   AbstractDirectory:list(invocation)
activate AbstractDirectory
AbstractDirectory   ->   RegistryDirectory:List<Invoker<T>> doList(invocation)
AbstractDirectory        ->   MockInvokersSelector:route(invokers,url,invocation)
AbstractDirectory        ->   AbstractClusterInvoker:return Invokers
deactivate AbstractDirectory
AbstractClusterInvoker   -> FailoverClusterInvoker:doInvoke(invocation, invokers, loadbalance)
activate FailoverClusterInvoker
FailoverClusterInvoker   -> AbstractClusterInvoker:Invoker select(loadbalance, Invocation invocation,invokers,selected)
FailoverClusterInvoker   -> FailoverClusterInvoker:invoker.invoke(invocation)
note left
获取需要执行的invoker，进行实际调用
endnote
FailoverClusterInvoker   -> AbstractClusterInvoker:返回Result
deactivate FailoverClusterInvoker
deactivate AbstractClusterInvoker

legend center
    1.在Directory中找出本次集群中的全部invokers
    2.在Router中,将上一步的全部invokers挑选出能正常执行的invokers
    3.在LoadBalance中,将上一步的能正常的执行invokers中,根据配置的负载均衡策略,挑选出需要执行的invoker
    PS:dubbo默认集群容错模式为failover；负载均衡策略默认为随机策略，当集群节点数为2时，退化成轮循
    这里的Invoker是Provider的一个可调用Service的抽象，Invoker封装了Provider地址及Service接口信息。
    Directory代表多个Invoker，可以把它看成List，但与List不同的是，它的值可能是动态变化的，比如注册中心推送变更。
    Cluster将Directory中的多个Invoker伪装成一个Invoker，对上层透明，伪装过程包含了容错逻辑，调用失败后，重试另一个。
    Router负责从多个Invoker中按路由规则选出子集，比如读写分离，应用隔离等。
    LoadBalance负责从多个Invoker中选出具体的一个用于本次调用，选的过程包含了负载均衡算法，调用失败后，需要重选。
endlegend

@enduml