Motan 调用执行流程

客户端服务接口所持有的对象为RefererInvocationHandler,jdk的代理实现,invoke调用,先封装DefaultRequest,遍历clusters,如果存在降级的则跳过,默认选第一个非降级的cluster

  • clusters处理
for (Cluster cluster : clusters) {
    String protocolSwitcher = MotanConstants.PROTOCOL_SWITCHER_PREFIX + cluster.getUrl().getProtocol();

    Switcher switcher = switcherService.getSwitcher(protocolSwitcher);
    // 跳过降级的cluster
    if (switcher != null && !switcher.isOn()) {
         continue;
    }
    // request设置各种数据
    // 最后通过cluster.call调用
    response = cluster.call(request);
}
  • 高可用策略处理
// cluster.call,通过配置的HA策略 来实现调用(默认配置:FailoverHaStrategy)
public Response call(Request request) {
    if (available.get()) {
        try {
            // loadBalance将在haStrategy中处理
            return haStrategy.call(request, loadBalance);
        } catch (Exception e) {
            return callFalse(request, e);
        }
    }
    return callFalse(request, new MotanServiceException(MotanErrorMsgConstant.SERVICE_UNFOUND));
}
  • 负载均衡处理
// 选择Refer,通过loadBalance.selectToHolder(request, referers);选择
List> referers = selectReferers(request, loadBalance);
URL refUrl = referers.get(0).getUrl();
//
// 从第一个url中获取重试次数
int tryCount = refUrl.getMethodParameter(request.getMethodName(), 
        request.getParamtersDesc(), URLParamType.retries.getName(),
        URLParamType.retries.getIntValue());
// 如果有问题,则设置为不重试
if (tryCount < 0) {
  tryCount = 0;
}
for (int i = 0; i <= tryCount; i++) {
  // 选择一个服务
  Referer refer = referers.get(i % referers.size());
  try {
    // 设置重试次数
    request.setRetries(i);
    // 开始远程调用
    return refer.call(request);
  } catch (RuntimeException e) {
  // 对于业务异常,直接抛出
  if (ExceptionUtil.isBizException(e)) {
    throw e;
  } else if (i >= tryCount) {
    throw e;
  }
  LoggerUtil.warn(String.format("FailoverHaStrategy Call false for request:%s error=%s", request, e.getMessage()));
}
// selectToHolder的处理(选择refers)
public void selectToHolder(Request request, List> refersHolder) {
  List> referers = this.referers;

  if (referers == null) {
    throw new MotanServiceException(this.getClass().getSimpleName() + " No available referers for call : referers_size= 0 "
                    + MotanFrameworkUtil.toString(request));
  }

  if (referers.size() > 1) {
    // 多于一个,继续选(这里就根据配置的负载均衡策略来处理,
    // 默认的是RoundRobinLoadBalance),但也会返回多个refer
    doSelectToHolder(request, refersHolder);
  } else if (referers.size() == 1 && referers.get(0).isAvailable()) {
    // 只有一个,只记录当前的
    refersHolder.add(referers.get(0));
  }
  if (refersHolder.isEmpty()) {
    throw new MotanServiceException(this.getClass().getSimpleName() + " No available referers for call : referers_size="
                    + referers.size() + " " + MotanFrameworkUtil.toString(request));
  }
}
  • refer.call最后在DefaultRpcProtocol的DefaultRpcReferer中通过NettyClient发出请求
protected Response doCall(Request request) {
    try {
      // 为了能够实现跨group请求,需要使用server端的group。
      request.setAttachment(URLParamType.group.getName(), serviceUrl.getGroup());
      return client.request(request);
    } catch (TransportException exception) {
      throw new MotanServiceException("DefaultRpcReferer call Error: url=" + url.getUri(), exception);
    }
}
  • 最终通过netty将消息发出
ChannelFuture writeFuture = this.channel.write(request);
// 注册一个回调,用来处理调用情况
response.addListener(new FutureListener() {
    @Override
    public void operationComplete(Future future) throws Exception {
        if (future.isSuccess() || (future.isDone() && ExceptionUtil.isBizException(future.getException()))) {
            // 成功的调用 
            nettyClient.resetErrorCount();
        } else {
            // 失败的调用 
            nettyClient.incrErrorCount();
        }
    }
});

服务器端通过Netty接收客户端的请求,入口为NettyChannelHandler的messageReceived

  • netty 处理
if (message instanceof Request) {
    processRequest(ctx, e);  // 处理客户端发来的请求
} else if (message instanceof Response) {
    processResponse(ctx, e);
}
//
// 使用线程池处理调用请求
threadPoolExecutor.execute(new Runnable() {
    @Override
    public void run() {
        try{
            RpcContext.init(request);
            processRequest(ctx, request, processStartTime);
        }finally{
            RpcContext.destroy();
        }
    }
});
  • ProviderProtectedMessageRouter处理
// key:motan-demo-rpc/com.weibo.motan.demo.service.MotanDemoService/1.0
String serviceKey = MotanFrameworkUtil.getServiceKey(request);
// 根据key获取Provider(DefaultProvider)
Provider provider = providers.get(serviceKey);
// 通过反射调用
Method method = lookup(request);
Object value = method.invoke(proxyImpl, request.getArguments());
  • 然后进入service层代码处理,后续就是结果返回处理了。

大概的示意图:


Motan 调用执行流程_第1张图片
call.png

你可能感兴趣的:(Motan 调用执行流程)