对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);
}