文章目录
- 流程图示
- 源码分析
-
- InvokerInvocationHandler.invoke
- MockClusterInvoker.invoke容错降级
- AbstractClusterInvoker.invoke 获取负载均衡实现以及服务端集合
- FailoverClusterInvoker.invoke 支持重试的clusterInvoker
- CallbackRegistrationInvoker监听过滤
- AsyncToSyncInvoker.invoke异步转同步
- dubboInvoker.doinvoke调用remote层远程通信
- 总结
流程图示
源码分析
InvokerInvocationHandler.invoke
- 代理入口,对方法的调用,代理拦截后调用invoker.invoke
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
...... 删除equals hashcode等方法调用
调用MockClusterInvoker 构建调用会话
return invoker.invoke(new RpcInvocation(method, args)).recreate();
}
MockClusterInvoker.invoke容错降级
- 配置force则直接降级
- 配置fail则失败降级
- 无配置正常调用服务端
public Result invoke(Invocation invocation) throws RpcException {
Result result = null;
获取容错降级配置
String value = directory.getUrl().getMethodParameter(invocation.getMethodName(), MOCK_KEY, Boolean.FALSE.toString()).trim();
if (value.length() == 0 || "false".equalsIgnoreCase(value)) {
step-1: 无配置直接调用
result = this.invoker.invoke(invocation);
} else if (value.startsWith("force")) {
step-2: 强制降级直接走降级逻辑 一般配置于dubbo面板
result = doMockInvoke(invocation, null);
} else {
step-3: 容错直接调用 异常走降级逻辑
try {
result = this.invoker.invoke(invocation);
区分rpc业务异常与远程调用异常
if(result.getException() != null && result.getException() instanceof RpcException){
RpcException rpcException= (RpcException)result.getException();
if(rpcException.isBiz()){
throw rpcException;
}else {
result = doMockInvoke(invocation, rpcException);
}
}
} catch (RpcException e) {
if (e.isBiz()) {
throw e;
}
result = doMockInvoke(invocation, e);
}
}
return result;
}
AbstractClusterInvoker.invoke 获取负载均衡实现以及服务端集合
- 通过directory获取服务端所有注册的提供者
- 通过url获取负载均衡实现
- 执行doinvoke
public Result invoke(final Invocation invocation) throws RpcException {
checkWhetherDestroyed();
添加上下文附件到远程会话对象上
Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
if (contextAttachments != null && contextAttachments.size() != 0) {
((RpcInvocation) invocation).addAttachments(contextAttachments);
}
通过directory获取服务端所有注册的提供者
List<Invoker<T>> invokers = list(invocation);
通过url获取负载均衡实现
LoadBalance loadbalance = initLoadBalance(invokers, invocation);
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
return doInvoke(invocation, invokers, loadbalance);
}
FailoverClusterInvoker.invoke 支持重试的clusterInvoker
- 循环重试
- 通过负载均衡选择Invoker
- 执行Invoker调用
public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
List<Invoker<T>> copyInvokers = invokers;
checkInvokers(copyInvokers, invocation);
String methodName = RpcUtils.getMethodName(invocation);
int len = getUrl().getMethodParameter(methodName, RETRIES_KEY, DEFAULT_RETRIES) + 1;
if (len <= 0) {
len = 1;
}
RpcException le = null;
List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyInvokers.size());
Set<String> providers = new HashSet<String>(len);
len表示重试次数
for (int i = 0; i < len; i++) {
...... 删除部分代码
负载均衡选择
Invoker<T> invoker = select(loadbalance, invocation, copyInvokers, invoked);
invoked.add(invoker);
RpcContext.getContext().setInvokers((List) invoked);
try {
Result result = invoker.invoke(invocation);
return result;
} catch (RpcException e) {
...... 删除部分代码
throw e;
}
}
...... 删除部分代码
}
CallbackRegistrationInvoker监听过滤
- 过滤器链执行 最后执行下一个Invoker
- ListenableFilter能够对asyncResult进行监听[这里代码删除]
@Override
public Result invoke(Invocation invocation) throws RpcException {
过滤器链执行 最后执行dubboInvoker
Result asyncResult = filterInvoker.invoke(invocation);
...... 删除具有监听功能的过滤器
return asyncResult;
}
AsyncToSyncInvoker.invoke异步转同步
public Result invoke(Invocation invocation) throws RpcException {
asyncResult是一个future
Result asyncResult = invoker.invoke(invocation);
如果同步则无限等待获取结果
if (InvokeMode.SYNC == ((RpcInvocation) invocation).getInvokeMode()) {
asyncResult.get(Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
}
...... 删除异常代码
如果异步直接返回future
return asyncResult;
}
dubboInvoker.doinvoke调用remote层远程通信
- 调用通信层进行远程通信
- 返回future对象,上层Invoker通过get阻塞
protected Result doInvoke(final Invocation invocation) throws Throwable {
RpcInvocation inv = (RpcInvocation) invocation;
final String methodName = RpcUtils.getMethodName(invocation);
接口名+端口号
inv.setAttachment(PATH_KEY, getUrl().getPath());
inv.setAttachment(VERSION_KEY, version);
获取ExchangeClient
...... 删除client的选择 一般默认就一个共享连接
...... 删除部分代码
boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
int timeout = getUrl().getMethodPositiveParameter(methodName, TIMEOUT_KEY, DEFAULT_TIMEOUT);
区分单边,比如心跳包等
if (isOneway) {
boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);
currentClient.send(inv, isSent);
return AsyncRpcResult.newDefaultAsyncResult(invocation);
} else {
核心
AsyncRpcResult asyncRpcResult = new AsyncRpcResult(inv);
进行请求
CompletableFuture<Object> responseFuture = currentClient.request(inv, timeout);
asyncRpcResult.subscribeTo(responseFuture);
FutureContext.getContext().setCompatibleFuture(responseFuture);
返回请求future对象,responseFuture并没有真正请求完毕,在异步转同步Invoker处阻塞
return asyncRpcResult;
}
}
总结
- 除去FailoverClusterInvoker还有多种容错策略
- 整个容错核心在于 ***ClusterInvoker
- 整个负载均衡核心在于loadbalance.select
- directory.list出了列举服务提供者集合,还处理了router路由过滤[tag,script,condition等]