服务调用流程:
服务的调用采用了代理模式,其代理对象是通过ProxyFactory生成的。
执行
invoker.invoke(new RpcInvocation(method, args)).recreate()。
进入到MockClusterInvoker(失败重试机制):
执行invoke方法,先进入AbstractClusterInvoker类查找注册中心注册代理类和负载均衡策略:
@Override
public Result invoke(final Invocation invocation) throws RpcException {
checkWhetherDestroyed();
LoadBalance loadbalance = null;
//从注册中心获取该方法对应的代理对象
List<Invoker<T>> invokers = list(invocation);
if (invokers != null && !invokers.isEmpty()) {
// 获取负载均衡机制
loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
.getMethodParameter(invocation.getMethodName(), Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
}
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
return doInvoke(invocation, invokers, loadbalance);
}
执行doInvoke()方法,根据失败策略确定执行哪一个Invoker类根据上述此处执行FailoverClusterInvoker.doInvoke()方法。
- Failover Cluster - 失败自动切换
- Failfast Cluster - 快速失败
- Failsafe Cluster - 失败安全
- Failback Cluster - 失败自动恢复
- Forking Cluster - 并行调用多个服务提供者
FailoverClusterInvoker.doInvoke():
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
。。。。。。。。。。。。。。
//根据负载均衡策略获取代理对象
Invoker<T> invoker = select(loadbalance, invocation, copyinvokers, invoked);
invoked.add(invoker);
RpcContext.getContext().setInvokers((List) invoked);
try {
//执行 根据代理执行方法获取最终的结果
Result result = invoker.invoke(invocation);
。。。。。。。。。。。。。。。
return result;
。。。。。。。。。。。。。。
}
在执行最终方法的时候,dubbo有提供了很多的filter进行数据处理如缓存,监听等拦截器。
根据图可以看出存在多个拦截器:ProtocolFilterWrapper
进入:MonitorFilter
最终会进入DubboInvoker连接客户端发送请求:
执行:
@Override
public ResponseFuture request(Object request, int timeout) throws RemotingException {
if (closed) {
throw new RemotingException(this.getLocalAddress(), null, "Failed to send request " + request + ", cause: The channel " + this + " is closed!");
}
// create request.
Request req = new Request();
req.setVersion("2.0.0");
req.setTwoWay(true);
req.setData(request);
DefaultFuture future = new DefaultFuture(channel, req, timeout);
try {
//通道发送数据
channel.send(req);
} catch (RemotingException e) {
future.cancel();
throw e;
}
return future;
}
得到执行结果返回数据:
例如:CacheFilter 缓存
调试代码:点击
参考来源:http://dubbo.apache.org/zh-cn/docs/user/configuration/xml.html