下面的源码包是本人在阅读《深度剖析Apache Dubbo核心技术内幕_翟陆续》这本书的过程中,按照书中的讲解一步步将全部注释在写好在源码中,这个过程也是学习的过程。
当然大家如果直接拿着这份写好注释的源码来阅读书籍的话,会更加方便了。
下面是一些源码摘录:
如失败重试策略 FailoverClusterInvoker:
// 1、所有服务提供者
List> copyInvokers = invokers;
checkInvokers(copyInvokers, invocation);
String methodName = RpcUtils.getMethodName(invocation);
// 2、获取重试次数
int len = getUrl().getMethodParameter(methodName, Constants.RETRIES_KEY, Constants.DEFAULT_RETRIES) +1;
if (len <=0) {
len =1;
}
// 3、使用循环,失败重试
// retry loop.
RpcException le =null;// last exception.
List> invoked =new ArrayList>(copyInvokers.size());// invoked invokers.
Set providers =new HashSet(len);
for (int i =0; i < len; i++) {
//Reselect before retry to avoid a change of candidate `invokers`.
//NOTE: if `invokers` changed, then `invoked` also lose accuracy.
// 重试时,进行重新选择,避免重试时invoker列表已经发生变化
// 注意:如果列表发生了变化,那么invoked判断会失效,因为invoker实例已经改变
if (i >0) {
// 3.1、如果当前实例已经被销毁,则抛出异常
checkWhetherDestroyed();
// 3.2、重新获取所有服务提供者
copyInvokers = list(invocation);
// check again
// 3.3、重新检查一下
checkInvokers(copyInvokers, invocation);
}
// 3.4、选择负载均衡策略
Invoker invoker = select(loadbalance, invocation, copyInvokers, invoked);
invoked.add(invoker);
RpcContext.getContext().setInvokers((List) invoked);
try {
// 3.5、具体发起远程调用
Result result = invoker.invoke(invocation);
return result;
}catch (RpcException e) {
if (e.isBiz()) {// biz exception.
throw e;
}
le = e;
}catch (Throwable e) {
le =new RpcException(e.getMessage(), e);
}finally {
providers.add(invoker.getUrl().getAddress());
}
}
dubbo的实际调用地方DubboInvoker:
protected Result doInvoke(final Invocation invocation)throws Throwable {
// 1、设置附加属性
RpcInvocation inv = (RpcInvocation) invocation;
final String methodName = RpcUtils.getMethodName(invocation);
inv.setAttachment(Constants.PATH_KEY, getUrl().getPath());
inv.setAttachment(Constants.VERSION_KEY,version);
// 2、获取远程调用Client
ExchangeClient currentClient;
if (clients.length ==1) {
currentClient =clients[0];
}else {
currentClient =clients[index.getAndIncrement() %clients.length];
}
// 3、执行远程调用
try {
// 3.1、是否为异步调用
boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
// 3.2、是否为future方式异步
boolean isAsyncFuture = RpcUtils.isReturnTypeFuture(inv);
// 3.3、是否为OneWay,也就是不需要响应结果的请求
boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
// 3.4、超时等待时间
int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
// 3.5、不需要响应结果的请求
if (isOneway) {
boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY,false);
currentClient.send(inv, isSent);
RpcContext.getContext().setFuture(null);
return new RpcResult();
}// 3.6、异步请求
else if (isAsync) {
ResponseFuture future = currentClient.request(inv, timeout);
// For compatibility
FutureAdapter futureAdapter =new FutureAdapter<>(future);
RpcContext.getContext().setFuture(futureAdapter);
// 3.6.1、异步future
Result result;
if (isAsyncFuture) {
// register resultCallback, sometimes we need the async result being processed by the filter chain.
result =new AsyncRpcResult(futureAdapter, futureAdapter.getResultFuture(),false);
}else {
result =new SimpleAsyncRpcResult(futureAdapter, futureAdapter.getResultFuture(),false);
}
return result;
}else {
// 3.7、同步请求
RpcContext.getContext().setFuture(null);
return (Result) currentClient.request(inv, timeout).get();
}
}catch (TimeoutException e) {
throw new RpcException(RpcException.TIMEOUT_EXCEPTION,"Invoke remote method timeout. method: " + invocation.getMethodName() +", provider: " + getUrl() +", cause: " + e.getMessage(), e);
}catch (RemotingException e) {
throw new RpcException(RpcException.NETWORK_EXCEPTION,"Failed to invoke remote method: " + invocation.getMethodName() +", provider: " + getUrl() +", cause: " + e.getMessage(), e);
}
}
完整的带注释的源码包下载地址: