背景:以sofa-rpc-master:5.6.0-SNAPSHOT版本为例,下载 代码,以
com.alipay.sofa.rpc.quickstart.QuickStartClient 和
com.alipay.sofa.rpc.quickstart.QuickStartServer 2个类运行作为举例说明
先debug运行QuickStartServer类的main方法,再运行QuickStartClient的main方法,然后。。。开始分析:
1.运行QuickStartClient之后,首先server端会在com.alipay.remoting.rpc.RpcHandler
类中的channelRead(ChannelHandlerContext ctx, Object msg)
方法中获取到client端的请求,如下所示:
2.进入handleCommand(RemotingContext ctx, Object msg)
方法实现,走到 com.alipay.remoting.rpc.protocol.RpcCommandHandler#handle(...)中。
接着进入到
3.进入com.alipay.remoting.rpc.protocol.RpcRequestProcessor#process(...)中
:
@Override
public void process(RemotingContext ctx, RpcRequestCommand cmd, ExecutorService defaultExecutor)
throws Exception {
/*
* 序列化类名称:requestClass=com.alipay.sofa.rpc.core.request.SofaRequest
*/
if (!deserializeRequestCommand(ctx, cmd, RpcDeserializeLevel.DESERIALIZE_CLAZZ)) {
return;
}
UserProcessor userProcessor = ctx.getUserProcessor(cmd.getRequestClass());
if (userProcessor == null) {
String errMsg = "No user processor found for request: " + cmd.getRequestClass();
logger.error(errMsg);
sendResponseIfNecessary(ctx, cmd.getType(), this.getCommandFactory()
.createExceptionResponse(cmd.getId(), errMsg));
return;// must end process
}
// set timeout check state from user's processor
ctx.setTimeoutDiscard(userProcessor.timeoutDiscard());
...
...
Executor executor = ...;
// 代码走到这里,下面在ProcessTask中run打断点
// use the final executor dispatch process task
executor.execute(new ProcessTask(ctx, cmd));
}
4.开始处理:
@Override
public void doProcess(final RemotingContext ctx, RpcRequestCommand cmd) throws Exception {
long currentTimestamp = System.currentTimeMillis();
preProcessRemotingContext(ctx, cmd, currentTimestamp);
if (ctx.isTimeoutDiscard() && ctx.isRequestTimeout()) {
timeoutLog(cmd, currentTimestamp, ctx);// do some log
return;// then, discard this request
}
debugLog(ctx, cmd, currentTimestamp);
// 看这里,1.序列化类;
// 2. 序列化头部:requestHeader值( requestCommand.setRequestHeader(headerMap);)
// 3. 序列化内容
// decode request all
if (!deserializeRequestCommand(ctx, cmd, RpcDeserializeLevel.DESERIALIZE_ALL)) {
return;
}
// 调度到用户处理器中处理
dispatchToUserProcessor(ctx, cmd);
}
序列化成功后的显示:
5. 进入到 com.alipay.sofa.rpc.server.bolt.BoltServerProcessor#handleRequest(...)
@Override
public void handleRequest(BizContext bizCtx, AsyncContext asyncCtx, SofaRequest request) {
// RPC内置上下文
RpcInternalContext context = RpcInternalContext.getContext();
context.setProviderSide(true);
String appName = request.getTargetAppName();
if (appName == null) {
// 默认全局appName
appName = (String) RpcRuntimeContext.get(RpcRuntimeContext.KEY_APPNAME);
}
// 是否链路异步化中
boolean isAsyncChain = false;
try { // 这个 try-finally 为了保证Context一定被清理
processingCount.incrementAndGet(); // 统计值加1
context.setRemoteAddress(bizCtx.getRemoteHost(), bizCtx.getRemotePort()); // 远程地址
context.setAttachment(RpcConstants.HIDDEN_KEY_ASYNC_CONTEXT, asyncCtx); // 远程返回的通道
if (RpcInternalContext.isAttachmentEnable()) {
InvokeContext boltInvokeCtx = bizCtx.getInvokeContext();
if (boltInvokeCtx != null) {
putToContextIfNotNull(boltInvokeCtx, InvokeContext.BOLT_PROCESS_WAIT_TIME,
context, RpcConstants.INTERNAL_KEY_PROCESS_WAIT_TIME); // rpc线程池等待时间 Long
}
}
// 事件总线数据模型:发送 server receive event 事件通知
if (EventBus.isEnable(ServerReceiveEvent.class)) {
EventBus.post(new ServerReceiveEvent(request));
}
// 开始处理
SofaResponse response = null; // 响应,用于返回
Throwable throwable = null; // 异常,用于记录
ProviderConfig providerConfig = null;
String serviceName = request.getTargetServiceUniqueName();
try { // 这个try-catch 保证一定有Response
invoke:
{
if (!boltServer.isStarted()) { // 服务端已关闭
throwable = new SofaRpcException(RpcErrorType.SERVER_CLOSED, LogCodes.getLog(
LogCodes.WARN_PROVIDER_STOPPED, SystemInfo.getLocalHost() + ":" +
boltServer.serverConfig.getPort()));
response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
break invoke;
}
if (bizCtx.isRequestTimeout()) { // 加上丢弃超时的请求的逻辑
throwable = clientTimeoutWhenReceiveRequest(appName, serviceName, bizCtx.getRemoteAddress());
break invoke;
}
// 查找服务【server export服务时创建好的Invoker】
Invoker invoker = boltServer.findInvoker(serviceName);
if (invoker == null) {
throwable = cannotFoundService(appName, serviceName);
response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
break invoke;
}
if (invoker instanceof ProviderProxyInvoker) {
providerConfig = ((ProviderProxyInvoker) invoker).getProviderConfig();
// 找到服务后,打印服务的appName
appName = providerConfig != null ? providerConfig.getAppName() : null;
}
// 查找方法
String methodName = request.getMethodName();
Method serviceMethod = ReflectCache.getOverloadMethodCache(serviceName, methodName,
request.getMethodArgSigs());
if (serviceMethod == null) {
throwable = cannotFoundServiceMethod(appName, methodName, serviceName);
response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
break invoke;
} else {
request.setMethod(serviceMethod);
}
// 真正调用【看这里~】
response = doInvoke(serviceName, invoker, request);
if (bizCtx.isRequestTimeout()) { // 加上丢弃超时的响应的逻辑
throwable = clientTimeoutWhenSendResponse(appName, serviceName, bizCtx.getRemoteAddress());
break invoke;
}
}
} catch (Exception e) {
// 服务端异常,不管是啥异常
LOGGER.errorWithApp(appName, "Server Processor Error!", e);
throwable = e;
response = MessageBuilder.buildSofaErrorResponse(e.getMessage());
}
// =================先别看下面的代码,回过头来再看========================
// Response不为空,代表需要返回给客户端
if (response != null) {
RpcInvokeContext invokeContext = RpcInvokeContext.peekContext();
isAsyncChain = CommonUtils.isTrue(invokeContext != null ?
(Boolean) invokeContext.remove(RemotingConstants.INVOKE_CTX_IS_ASYNC_CHAIN) : null);
// 如果是服务端异步代理模式,特殊处理,因为该模式是在业务代码自主异步返回的
if (!isAsyncChain) {
// 其它正常请求
try { // 这个try-catch 保证一定要记录tracer
asyncCtx.sendResponse(response);
} finally {
if (EventBus.isEnable(ServerSendEvent.class)) {
EventBus.post(new ServerSendEvent(request, response, throwable));
}
}
}
}
} catch (Throwable e) {
// 可能有返回时的异常
if (LOGGER.isErrorEnabled(appName)) {
LOGGER.errorWithApp(appName, e.getMessage(), e);
}
} finally {
processingCount.decrementAndGet();
if (!isAsyncChain) {
if (EventBus.isEnable(ServerEndHandleEvent.class)) {
EventBus.post(new ServerEndHandleEvent());
}
}
RpcInvokeContext.removeContext();
RpcInternalContext.removeAllContext();
}
}
6.进入上面的 com.alipay.sofa.rpc.server.bolt.BoltServerProcessor#doInvoke(...)
进入拦截器调用链:
最后真正的调用代码在com.alipay.sofa.rpc.filter.ProviderInvoker#invoke(...)
@Override
public SofaResponse invoke(SofaRequest request) throws SofaRpcException {
SofaResponse sofaResponse = new SofaResponse();
long startTime = RpcRuntimeContext.now();
try {
// 反射 真正调用业务代码
Method method = request.getMethod();
if (method == null) {
throw new SofaRpcException(RpcErrorType.SERVER_FILTER, "Need decode method first!");
}
Object result = method.invoke(providerConfig.getRef(), request.getMethodArgs());
sofaResponse.setAppResponse(result);
} catch (IllegalArgumentException e) { // 非法参数,可能是实现类和接口类不对应)
sofaResponse.setErrorMsg(e.getMessage());
} catch (IllegalAccessException e) { // 如果此 Method 对象强制执行 Java 语言访问控制,并且底层方法是不可访问的
sofaResponse.setErrorMsg(e.getMessage());
} catch (InvocationTargetException e) { // 业务代码抛出异常
sofaResponse.setAppResponse(e.getCause());
} finally {
if (RpcInternalContext.isAttachmentEnable()) {
long endTime = RpcRuntimeContext.now();
RpcInternalContext.getContext().setAttachment(RpcConstants.INTERNAL_KEY_IMPL_ELAPSE,
endTime - startTime);
}
}
return sofaResponse;
}
这样就进到了example中,真正的业务方法调用了:
7.最后回到com.alipay.sofa.rpc.server.bolt.BoltServerProcessor#handleRequest(...)
:
如上所示:server处理完成后,发送响应数据给client,并在事件总线上发送 server send event 事件。