关于Dubbo的重试机制

一、重试机制

Dubbo消费端的ClusterInvoker中,只有当异常是业务的RPC异常(isBiz() == true)时不会重试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
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;
}
// 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++) {
//Reselect before retry to avoid a change of candidate `invokers`.
//NOTE: if `invokers` changed, then `invoked` also lose accuracy.
if (i > 0) {
checkWhetherDestroyed();
copyInvokers = list(invocation);
// check again
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);
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.getCode(), "Failed to invoke");
}
}
阅读更多

RPC服务线程池大小及集群规模评估

写在前面的话

一个RPC服务在发布时不可避免的要设置其线程池大小,而我们往往却只根据经验来设置,需知不同场景不同业务下其需要配置不同的值方能使系统更稳定。以下内容是我认为应该去考虑的因素和具体的一些步骤,留待慢慢验证。

一、评估单机最佳线程数

阅读更多

Dubbo扩展点

一、Dubbo扩展点

1、Dubbo扩展点来源

Dubbo 的扩展点加载从 JDK 标准的 SPI (Service Provider Interface) 扩展点发现机制加强而来。

阅读更多

Dubbo速览

Dubbo现在是业内广泛使用的RPC框架,通过速览其架构,概念和涉及的技术,我们可以快速理解和掌握RPC的使用及原理。

一、Dubbo架构

Dubbo涉及以下几个交互组件:

阅读更多