1 发送消息的整体流程
1.1 主要调用流程
- 调用远程接口,执行对应代理 (代理构建)
- 代理中调用Filter过滤链、执行Cluster(Invoker)(执行链的构建和执行)
- ClusterInvoker中先路由出一批Invoker列表、在负载均衡出唯一的调用者Invoker(筛选唯一Invoker)
- Invoker调用交换层进行网络发送数据
- 交换层发送数据、协议编码
2 代理创建
Deployer 、RefrenceCache、RefrenceConfig、Protocol、Invoker、Directory、Listener、JavasissitProxy
-
DubboDeployApplicationListener Spring启动监听器启动进行初始化操作 启动ModuleDeployer
- DefaultModuleDeployer#start Deployer启动中进行导入需要的服务引用
-
SimpleReferenceCache从缓存中获取服务引用、如果没有进行创建服务的引用
-
ReferenceConfig中进行初始化创建服务的引用,createInvokerForRemote创建服务的invoker引用,通过protocol创建服务引用(Invoker)
- RegistryProtocol#doRefer 创建ClusterInvoker,interceptInvoker方法中出发对应的监听器
MigrationRuleListener
-
ServiceDiscoveryRegistryDirectory 监听器中触发Directory订阅注册中心
- ServiceDiscoveryRegistry#subscribeURLs订阅注册中心触发监听器ServiceInstancesChangedListener
- 在监听器中获取远程元数据、接着创建对应的代理类
3 构建filterInvoker链
filterInvoker的数据结构
filterInvoker的数据结构 执行流程
FilterChainBuilder.CopyOfFilterChainNode#invoke执行
@Override
public Result invoke(Invocation invocation) throws RpcException {
Result asyncResult;
try {
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
// filter: ConsumerContextFilter
// nextNode: FilterChainBuilder.CopyOfFilterChainNode
asyncResult = filter.invoke(nextNode, invocation);
} catch (Exception e) {
InvocationProfilerUtils.releaseDetailProfiler(invocation);
if (filter instanceof ListenableFilter) {
ListenableFilter listenableFilter = ((ListenableFilter) filter);
try {
Filter.Listener listener = listenableFilter.listener(invocation);
if (listener != null) {
listener.onError(e, originalInvoker, invocation);
}
} finally {
listenableFilter.removeListener(invocation);
}
} else if (filter instanceof FILTER.Listener) {
FILTER.Listener listener = (FILTER.Listener) filter;
listener.onError(e, originalInvoker, invocation);
}
throw e;
} finally {
}
return asyncResult;
}
ConsumerContextFilter#invoke
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
...
// FilterChainBuilder.CopyOfFilterChainNode.invoke
return invoker.invoke(invocation);
} finally {
RpcContext.restoreServiceContext(originServiceContext);
}
}
@Override
public Result invoke(Invocation invocation) throws RpcException {
Result asyncResult;
try {
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
// filter: FutureFilter
// nextNode: FilterChainBuilder.CopyOfFilterChainNode
asyncResult = filter.invoke(nextNode, invocation);
} catch (Exception e) {
InvocationProfilerUtils.releaseDetailProfiler(invocation);
if (filter instanceof ListenableFilter) {
ListenableFilter listenableFilter = ((ListenableFilter) filter);
try {
Filter.Listener listener = listenableFilter.listener(invocation);
if (listener != null) {
listener.onError(e, originalInvoker, invocation);
}
} finally {
listenableFilter.removeListener(invocation);
}
} else if (filter instanceof FILTER.Listener) {
FILTER.Listener listener = (FILTER.Listener) filter;
listener.onError(e, originalInvoker, invocation);
}
throw e;
} finally {
}
return asyncResult;
}
- FilterChainBuilder.CopyOfFilterChainNode作为节点的包装节点包含两个 filter和nextNode
- filter.invoke执行的最后会执行nextNode.invoke,而nextNode又是FilterChainBuilder.CopyOfFilterChainNode(包含下一个filter和nextNode)的节点
- 这样通过节点中filter调用下个节点,下个节点的过滤器再调用下下个节点,形成啦filter执行链路
4 获取最原始的Invoker列表
- 订阅注册中心或者注册中心中被引用的服务发生变化,触发对应的监听器
- 监听器中刷新被引用的服务缓存,刷新routerChain中的Invoker列表
5 筛选唯一Invoker的流程(路由 )
AbstractClusterInvoker#invoke
@Override
public Result invoke(final Invocation invocation) throws RpcException {
checkWhetherDestroyed();
// binding attachments into invocation.
// Map<String, Object> contextAttachments = RpcContext.getClientAttachment().getObjectAttachments();
// if (contextAttachments != null && contextAttachments.size() != 0) {
// ((RpcInvocation) invocation).addObjectAttachmentsIfAbsent(contextAttachments);
// }
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Router route.");
List<Invoker<T>> invokers = list(invocation); //1 获取invoker执行列表(经过路由列表、和指定策略的路由,筛选符合条件的Invoker列表)
InvocationProfilerUtils.releaseDetailProfiler(invocation);
// 获取负载均衡器
LoadBalance loadbalance = initLoadBalance(invokers, invocation); // 2 初始化负载均衡器
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Cluster " + this.getClass().getName() + " invoke.");
try {
return doInvoke(invocation, invokers, loadbalance); //3 通过负载均衡筛选出唯一的Invoker
} finally {
InvocationProfilerUtils.releaseDetailProfiler(invocation);
}
}
stateRouter过滤之后再有普通路由列表依次进行过滤
6 筛选唯一Invoker的流程(负载均衡 )
获取唯一的负载均衡器
使用负载均衡器获取唯一的Invoker
随机负载均衡器
(支持设置invoker权重)
7 Invoker执行交换层进行数据的发送
DubboInvoker 执行ExchangeClient发送Channel数据
8 BitList分析
存储Invoker列表用的是BitList,方便对路由和负载均衡对结果的筛选和缓存。
-
BitList由三部分组成 rootSet、originList、tailList
- originList是一个原始的最全的元素结合,
- rootSet 标识originList中哪些元素是存在的哪些是不存在的,通过对rootSet的位操作来修改或者获取Invoker结果。通过对rootSet的与或运算来对元素进行筛选和操作BitSet计算效率高、内存占用小
- tailList 对最终结果拼接其他元素的列表
9 后续章节
- exchangeclient发送数据的详细流程(建立连接、发送数据、协议编码等)
- 服务端接受消息的处理流程(解码、线程模型)
- 服务端启动流程
- 责任链的应用
- 监听器的应用