当我们获取到引用接口的代理时
//调用
demoService.sayHello("world");
会进入到
//InvokerInvocationHandler
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
RpcInvocation invocation;
//封装请求参数
invocation = new RpcInvocation(method, args);
return invoker.invoke(invocation).recreate();
}
然后到
//MockClusterInvoker 获取代理时new进来的
//根据不同的 "mock" 配置,调用真正的Invoker 和 Mock 的 Invoker
public Result invoke(Invocation invocation) throws RpcException {
Result result = null;
//invoker,directory是在返回代理时new MockClusterInvoker 放入的
String value = directory.getUrl().getMethodParameter(invocation.getMethodName(), "mock", Boolean.FALSE.toString()).trim();
if (value.length() == 0 || value.equalsIgnoreCase("false")) {
//1.no mock // 调用原 Invoker ,发起 RPC 调用
result = this.invoker.invoke(invocation);//进入AbstractClusterInvoker
到
//AbstractClusterInvoker
public Result invoke(final Invocation invocation) throws RpcException {
checkWhetherDestroyed();// 校验是否销毁
// binding attachments into invocation.
Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
if (contextAttachments != null && contextAttachments.size() != 0) {
((RpcInvocation) invocation).addAttachments(contextAttachments);
}
// 获得所有服务提供者 Invoker 集合
List<Invoker<T>> invokers = list(invocation);//-->进入6 7
//获得 LoadBalance 对象
LoadBalance loadbalance = initLoadBalance(invokers, invocation);//8
// 设置调用编号,若是异步调用
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
// 执行调用(子Cluster的Invoker实现类的服务调用的差异逻辑。)
return doInvoke(invocation, invokers, loadbalance);
}
到
//FailoverClusterInvoker
public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
List<Invoker<T>> copyinvokers = invokers;
checkInvokers(copyinvokers, invocation);// 检查copyinvokers即可用Invoker集合是否为空,如果为空,那么抛出异常
String methodName = RpcUtils.getMethodName(invocation);
// 得到最大可调用次数:最大可重试次数+1,默认最大可重试次数Constants.DEFAULT_RETRIES=2
int len = getUrl().getMethodParameter(methodName, "retries", 2) + 1;
if (len <= 0) {
len = 1;
}
// retry loop.
RpcException le = null; // 保存最后一次调用的异常
// 保存已经调用过的Invoker
List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyinvokers.size()); // invoked invokers.
Set<String> providers = new HashSet<String>(len);
// failover机制核心实现:如果出现调用失败,那么重试其他服务器
for (int i = 0; i < len; i++) {
if (i > 0) {
//i > 0进行重新选择,避免重试时,候选 Invoker 集合,已发生变化。
checkWhetherDestroyed();
copyinvokers = list(invocation);
// check again
checkInvokers(copyinvokers, invocation);
}
// 根据负载均衡机制从copyinvokers中选择一个Invoker
Invoker<T> invoker = select(loadbalance, invocation, copyinvokers, invoked);//9
// 保存每次调用的Invoker
invoked.add(invoker);
// 设置已经调用的 Invoker 集合,到 Context 中
RpcContext.getContext().setInvokers((List) invoked);
try {// RPC 调用得到 Result
Result result = invoker.invoke(invocation);
到
//InvokerWrapper
public Result invoke(Invocation invocation) throws RpcException {
return invoker.invoke(invocation);
}
到
//ListenerInvokerWrapper
public Result invoke(Invocation invocation) throws RpcException {
return invoker.invoke(invocation);
}
到
//ProtocolFilterWrapper
private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
Invoker<T> last = invoker;
List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class)
.getActivateExtension(invoker.getUrl(), key, group);
if (!filters.isEmpty()) {
for (int i = filters.size() - 1; i >= 0; i--) {//倒叙循环
final Filter filter = filters.get(i);
final Invoker<T> next = last;
last = new Invoker<T>() {
public Result invoke(Invocation invocation) throws RpcException {
return filter.invoke(next, invocation);}
public Class<T> getInterface() {return invoker.getInterface();}
public URL getUrl() {return invoker.getUrl();}
public boolean isAvailable() {
return invoker.isAvailable();
}
public void destroy() {invoker.destroy();}
public String toString() {return invoker.toString();
}
};
}//for结束
}//if结束
return last;
}
到
//ConsumerContextFilter
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
RpcContext.getContext()
.setInvoker(invoker)
.setInvocation(invocation)
.setLocalAddress(NetUtils.getLocalHost(), 0)
.setRemoteAddress(invoker.getUrl().getHost(),
invoker.getUrl().getPort());
if (invocation instanceof RpcInvocation) {
((RpcInvocation) invocation).setInvoker(invoker);
}
try {
// TODO should we clear server context?
RpcContext.removeServerContext();
return postProcessResult(invoker.invoke(invocation), invoker, invocation);
} finally {
// TODO removeContext? but we need to save future for RpcContext.getFuture() API. If clear attachments here, attachments will not available when postProcessResult is invoked.
RpcContext.getContext().clearAttachments();
}
}
到
//FutureFilter
public Result invoke(final Invoker<?> invoker, final Invocation invocation) throws RpcException {
fireInvokeCallback(invoker, invocation);
return postProcessResult(invoker.invoke(invocation), invoker, invocation);
}
到
//MonitorFilter
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) {
RpcContext context = RpcContext.getContext(); // provider must fetch context before invoke() gets called
String remoteHost = context.getRemoteHost();
long start = System.currentTimeMillis(); // record start timestamp
getConcurrent(invoker, invocation).incrementAndGet(); // count up
try {
Result result = invoker.invoke(invocation); // proceed invocation chain
collect(invoker, invocation, result, remoteHost, start, false);
return result;
} catch (RpcException e) {
collect(invoker, invocation, null, remoteHost, start, true);
throw e;
} finally {
getConcurrent(invoker, invocation).decrementAndGet(); // count down
}
} else {
return invoker.invoke(invocation);
}
}
到
//AbstractInvoker
public Result invoke(Invocation inv) throws RpcException {
if (destroyed.get()) {
throw new RpcException("Rpc invoker for service " + this + " on consumer " + NetUtils.getLocalHost()
+ " use dubbo version " + Version.getVersion()
+ " is DESTROYED, can not be invoked any more!");
}
RpcInvocation invocation = (RpcInvocation) inv;
invocation.setInvoker(this);
if (attachment != null && attachment.size() > 0) {
invocation.addAttachmentsIfAbsent(attachment);
}
Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
if (contextAttachments != null && contextAttachments.size() != 0) {
invocation.addAttachments(contextAttachments);
}
if (getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false)) {
invocation.setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString());
}
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
try {
return doInvoke(invocation);
到
//DubboInvoker
currentClient.request(inv, timeout).get();
//ReferenceCountExchangeClient
public ResponseFuture request(Object request, int timeout) throws RemotingException {
return client.request(request, timeout);
}
//HeaderExchangeClient
public ResponseFuture request(Object request, int timeout) throws RemotingException {
return channel.request(request, timeout);
}
channel.send(req);
//AbstractPeer
public void send(Object message) throws RemotingException {
send(message, url.getParameter(Constants.SENT_KEY, false));
}
//AbstractClient
public void send(Object message, boolean sent) throws RemotingException {
if (send_reconnect && !isConnected()) {
connect();// 未连接时,开启重连功能,则先发起连接
}
Channel channel = getChannel();// 发送消息
//TODO Can the value returned by getChannel() be null? need improvement.
if (channel == null || !channel.isConnected()) {
throw new RemotingException(this, "message can not send, because channel is closed . url:" + getUrl());
}
channel.send(message, sent);
}
//NettyChannel
ChannelFuture future = channel.writeAndFlush(message);
最后。附上一张图
