dubbo的重试机制

2022-03-28 19:13:52 浏览数 (1)

对dubbo熟悉的人对下面的配置一定不会陌生:

代码语言:javascript复制
<dubbo:reference id="xxxx" interface="xx" check="true" async="false" retries="1" timeout="2000"/>

上面设置需要关注的几个地方:

1.check=true--系统在启动时就会去检查对应的dubbo服务,不存在就报错导致启动失败,所以如果设置为true,就必须确保该服务提供者一定要在该应用启动之前启动,否则就会启动失败

2.async--false,表明该服务是同步调用而不是异步调用

3.retries="1" 重试一次,也就是最多尝试2次,如果失败就抛出异常

4.timeout="2000" 服务超时时间(单位为毫秒),客户端在调用该dubbo服务时会启动超时检测,如果达到2秒就会报超时异常,超时异常后客户端会尝试1次调用,不管失败与否都返回。

注:需要注意的地方是timeout只有在超时异常才有效,如果是其他异常导致dubbo服务调用抛异常,会立即进入下一次尝试,直接看FailoverClusterInvoker(该类是dubbo默认使用的集群调用使用的类)类相关代码:

代码语言:javascript复制
public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
 List<Invoker<T>> copyinvokers = invokers;
 checkInvokers(copyinvokers, invocation);
         int len = getUrl().getMethodParameter(invocation.getMethodName(), Constants.RETRIES_KEY, Constants.DEFAULT_RETRIES)   1;
         if (len <= 0) {
             len = 1;
         }
         // retry loop.
         RpcException le = null; // last exception.
         List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyinvokers.size()); // invoked invokers.
         Set<String> providers = new HashSet<String>(len);
         for (int i = 0; i < len; i  ) {
 if (i > 0) {
 checkWheatherDestoried();
 copyinvokers = list(invocation);
 //
 checkInvokers(copyinvokers, invocation);
 }
             Invoker<T> invoker = select(loadbalance, invocation, copyinvokers, invoked);
             invoked.add(invoker);
             RpcContext.getContext().setInvokers((List)invoked);
             try {
                 Result result = invoker.invoke(invocation);
                 if (le != null && logger.isWarnEnabled()) {
                     logger.warn("Although retry the method "   invocation.getMethodName()
                               " in the service "   getInterface().getName()
                               " was successful by the provider "   invoker.getUrl().getAddress()
                               ", but there have been failed 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);
                 }
                 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());
             }
         }
         throw new RpcException(le != null ? le.getCode() : 0, "Failed to invoke the method "
                   invocation.getMethodName()   " 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 != null ? le.getMessage() : ""), le != null && le.getCause() != null ? le.getCause() : le);
     }
 

0 人点赞