本文讨论的原理是,假设dubbo框架使用protocol是"dubbo",server和client底层传输数据是"netty"。
原理机制
远程调用时,发送请求的封装对象
com.alibaba.dubbo.remoting.exchange.Request
远程调用时,接收返回的封装对象
com.alibaba.dubbo.remoting.exchange.Response
请求发出后,返回一个com.alibaba.dubbo.remoting.exchange.ResponseFuture对象,
ResponseFuture的默认实现类com.alibaba.dubbo.remoting.exchange.support.DefaultFuture
在我们的业务层调用dubbo封装的service时,dubbo底层会调用com.alibaba.dubbo.rpc.protocol.dubbo.DubboInvoker<T>的doInvoke方法:
public interface Invocation {
String getMethodName();
Class<?>[] getParameterTypes();
Object[] getArguments();
Map<String, String> getAttachments();
String getAttachment(String key);
String getAttachment(String key, String defaultValue);
Invoker<?> getInvoker();
}
可以看出,Invocation对象封装了消费者调用提供者的
类名: getInvoker()返回Invoker可以获得接口名;
方法名: getMethodName();
参数类型列表: getParameterTypes();
参数值列表: getArguments();
@Override
protected Result doInvoke(final Invocation invocation) throws Throwable {
RpcInvocation inv = (RpcInvocation) invocation;
final String methodName = RpcUtils.getMethodName(invocation);
inv.setAttachment(Constants.PATH_KEY, getUrl().getPath());
inv.setAttachment(Constants.VERSION_KEY, version);
ExchangeClient currentClient;
if (clients.length == 1) {
currentClient = clients[0];
} else {
currentClient = clients[index.getAndIncrement() % clients.length];
}
try {
boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY,Constants.DEFAULT_TIMEOUT);
if (isOneway) {
boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);
currentClient.send(inv, isSent);
RpcContext.getContext().setFuture(null);
return new RpcResult();
} else if (isAsync) { //11处,调用服务的结果,异步返回模式。
ResponseFuture future = currentClient.request(inv, timeout) ; //12处,向提供者发送消息
RpcContext.getContext().setFuture(new FutureAdapter<Object>(future));
return new RpcResult();
} else {
RpcContext.getContext().setFuture(null);
return (Result) currentClient.request(inv, timeout).get(); //13处,调用服务的结果,同步返回结果
}
} catch (TimeoutException e) {
throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
} catch (RemotingException e) {
throw new RpcException(RpcException.NETWORK_EXCEPTION, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
}
}
如果调用服务,是异步返回结果,则是"11处",其中"12处"是向提供者发送服务消息。
如果调用服务,是同步返回结果,则是"13处",currentClient.request(inv, timeou