publicResultdoInvoke(Invocation invocation,finalList<Invoker<T>> invokers,LoadBalance loadbalance)throwsRpcException{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;}// retry loop.RpcException le =null;// last exception.List<Invoker<T>> invoked =newArrayList<Invoker<T>>(copyInvokers.size());// invoked invokers.Set<String> providers =newHashSet<String>(len);
第一次加两次重试循环
for(int i =0; i < len; i++){if(i >0){checkWhetherDestroyed();
在进行重试前重新列举 Invoker,这样做的好处是,如果某个服务挂了, 通过调用 list 可得到最新可用的 Invoker 列表原因是register是监听zk的
copyInvokers =list(invocation);
check again
checkInvokers(copyInvokers, invocation);}
通过负载均衡策略选择InvokerInvoker<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){if(e.isBiz()){throw e;}
le = e;}catch(Throwable e){
le =newRpcException(e.getMessage(), e);}finally{
providers.add(invoker.getUrl().getAddress());}}
重试都失败则抛出异常
thrownewRpcException(le.getCode(),"Failed to invoke the method "+ methodName +" in the service "+getInterface().getName()+". Tried "+ len +" times of the providers "+ providers
+" ("+ providers.size()+"/"+ copyInvokers.size()+") from the registry "+ directory.getUrl().getAddress()+" on the consumer "+NetUtils.getLocalHost()+" using the dubbo version "+Version.getVersion()+". Last error is: "+ le.getMessage(), le.getCause()!=null? le.getCause(): le);}
文章目录FailoverClusterInvoker总结FailoverClusterInvoker重试会重新调用list(获取提供者集合外加路由)获取最新Invoker结果,因提供者可能有变动,重新获取本地缓存,确保监听变更后的RegisterDirectory能被及时感知重试通过循环实现 public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance