上一篇 :Pigeon的一次调用客户端发生了什么
接着上一篇,来看一下在这一次请求中服务端发生了什么
首先来看下服务端的启动
public static void init() {
if (!isInitialized) {
synchronized (ProviderBootStrap.class) {
if (!isInitialized) {
//调用链初始化
ProviderProcessHandlerFactory.init();
//序列化工厂,负责编解码
SerializerFactory.init();
ClassUtils.loadClasses("com.dianping.pigeon");
//关闭钩子,主要内容:服务下线,客户端和服务端关闭
Thread shutdownHook = new Thread(new ShutdownHookListener());
......
//初始化服务配置,并默认传输协议为HTTP
ServerConfig config = new ServerConfig();
config.setProtocol(Constants.PROTOCOL_HTTP);
//注册服务管理
RegistryManager.getInstance();
//ServiceLoader加载服务类:nettyServer
List<Server> servers = ExtensionLoader.getExtensionList(Server.class);
for (Server server : servers) {
if (!server.isStarted()) {
if (server.support(config)) {
//netty服务端启动,共享线程池的初始化都在这里完成
server.start(config);
....
....
}
}
}
isInitialized = true;
}
}
}
}
我们可以看到整个服务端的初始化流程以及启动流程(通过server.start(config)完成netty的启动),其中nettyServer是通过ServiceLoader加载初始化的(Java中的SPI机制是基于接口的编程+策略模式+配置文件的组合方式实现的动态加载机制),其初始化配置如图
接着看下其Pipeline配置
可以看到同客户端是基本一致的,接着我们看下pigeon的自定义handler对请求的处理是什么样的
可以看到其中是通过server.processRequest方法对请求进行了处理,我们进去看它的调用,最终负责处理逻辑的是doProcessRequest(request, providerContext)方法,看一下实现
public Future<InvocationResponse> doProcessRequest(final InvocationRequest request,
final ProviderContext providerContext) {
requestContextMap.put(request, providerContext);
startMonitorData(request, providerContext);
Callable<InvocationResponse> requestExecutor = new Callable<InvocationResponse>() {
@Override
public InvocationResponse call() throws Exception {
providerContext.getTimeline().add(new TimePoint(TimePhase.T));
try {
//调用了ProviderProcessHandlerFactory中构建的filter链
ServiceInvocationHandler invocationHandler = ProviderProcessHandlerFactory
.selectInvocationHandler(providerContext.getRequest().getMessageType());
if (invocationHandler != null) {
providerContext.setThread(Thread.currentThread());
return invocationHandler.handle(providerContext);
}
} catch (Throwable t) {
logger.error("Process request failed with invocation handler, you should never be here.", t);
} finally {
requestContextMap.remove(request);
}
return null;
}
};
final ThreadPool pool = selectThreadPool(request);
try {
checkRequest(pool, request);
providerContext.getTimeline().add(new TimePoint(TimePhase.T));
return pool.submit(requestExecutor);
} catch (RejectedExecutionException e) {
requestContextMap.remove(request);
endMonitorData(request, providerContext);
throw new RejectedException(getProcessorStatistics(pool), e);
}
}
这里调用了ProviderProcessHandlerFactory中构建的filter链,这里根据消息的类型调用不同的链路,然后交给了请求绑定的线程池(共享线程池、慢线程池、自定义线程池中的一种)去执行,可以看到其核心调用逻辑是在ProviderProcessHandlerFactory中构建的filter链,一起来看一下服务端的filter链是怎样的
public static void init() {
//请求初始的一些定义
registerBizProcessFilter(new ProviderContextFilter());
//监控相关
registerBizProcessFilter(new TracerFilter());
if (Constants.MONITOR_ENABLE) {
registerBizProcessFilter(new MonitorProcessFilter());
}
registerBizProcessFilter(new InnerTracerFilter());
registerBizProcessFilter(new TrafficRecordFilter());
//负责传数据给客户端的filter
registerBizProcessFilter(new WriteResponseProcessFilter());
//上下文处理
registerBizProcessFilter(new ContextTransferProcessFilter());
registerBizProcessFilter(new ExceptionProcessFilter());
//通用调用处理
registerBizProcessFilter(new GenericProcessFilter());
//安全相关
registerBizProcessFilter(new SecurityFilter());
//统计信息
registerBizProcessFilter(new GatewayProcessFilter());
//服务方法调用
registerBizProcessFilter(new BusinessProcessFilter());
//基础调用链
bizInvocationHandler = createInvocationHandler(bizProcessFilters);
//心跳相关责任链
registerHeartBeatProcessFilter(new WriteResponseProcessFilter());
registerHeartBeatProcessFilter(new HeartbeatProcessFilter());
heartBeatInvocationHandler = createInvocationHandler(heartBeatProcessFilters);
registerHealthCheckProcessFilter(new WriteResponseProcessFilter());
registerHealthCheckProcessFilter(new HealthCheckProcessFilter());
healthCheckInvocationHandler = createInvocationHandler(healthCheckProcessFilters);
registerScannerHeartBeatProcessFilter(new WriteResponseProcessFilter());
registerScannerHeartBeatProcessFilter(new ScannerHeartBeatProcessFilter());
scannerHeartBeatInvocationHandler = createInvocationHandler(scannerHeartBeatProcessFilters);
}
可以看到ProviderProcessHandlerFactory中一共构建了四种filter链,我们这里要看的主要是bizProcessFilters调用链,这是负责数据处理和传输的链路,其中WriteResponseProcessFilter负责数据的返回,BusinessProcessFilter负责服务本地方法的调用,来看下它的实现
public InvocationResponse invoke(ServiceInvocationHandler handler, ProviderContext invocationContext)
throws Throwable {
invocationContext.getTimeline().add(new TimePoint(TimePhase.U));
InvocationRequest request = invocationContext.getRequest();
if (request.getMessageType() == Constants.MESSAGE_TYPE_SERVICE) {
if (timeoutReseted && request.getTimeout() > 0) {
ContextUtils.putLocalContext(Constants.REQUEST_TIMEOUT, request.getTimeout());
}
.....
.....
InvocationResponse response = null;
ServiceMethod method = invocationContext.getServiceMethod();
if (method == null) {
method = ServiceMethodFactory.getMethod(request);
}
ProviderHelper.setContext(invocationContext);
invocationContext.getTimeline().add(new TimePoint(TimePhase.M, System.currentTimeMillis()));
Object returnObj = null;
try {
//服务执行方法调用
returnObj = method.invoke(request.getParameters());
} finally {
ProviderHelper.clearContext();
if (Constants.REPLY_MANUAL || invocationContext.isAsync()) {
if (request.getCallType() == Constants.CALLTYPE_REPLY) {
request.setCallType(Constants.CALLTYPE_MANUAL);
}
}
}
invocationContext.getTimeline().add(new TimePoint(TimePhase.M, System.currentTimeMillis()));
if (request.getCallType() == Constants.CALLTYPE_REPLY) {
response = ProviderUtils.createSuccessResponse(request, returnObj);
}
return response;
}
throw new BadRequestException("message type[" + request.getMessageType() + "] is not supported!");
}
我们知道服务端暴露给客户端的api是接口,客户端通过接口api调用相关方法(通过动态代理调用服务),那么服务端是怎么根据接口找到请求匹配的方法实现的呢?
从上面可以看到是通过调用 ServiceMethodFactory.getMethod(request);获取的方法,看一下它的实现
通过getServiceMethodCache(newUrl)获得服务方法缓存,然后从serviceMethodCache(存了对应服务所有的方法信息,其中有一个根据方法名和参数个数保存的Map方法集合)中去获取方法,接着进去看下
这里的核心方法是getBestMatchMethod(methodName, paramNames)方法,该方法作用:找到匹配度最高的方法(根据参数匹配),然后将结果方法缓存bestMacthMethod里,以待下次直接获取,无需再行匹配,最后将匹配到的方法返回。
得到匹配的method会通过反射去执行对应服务方法的实现,然后返回结果给外层Filter ,并由WriteResponseProcessFilter完成数据的发送。
这里要注意的是pigeon不管是客户端还是服务端,都是使用类Filter的责任链执行流程,调用过程其实是从上到下执行,再从下到上的返回调用(上层Filter嵌套下层Filter),从链路处理逻辑中我们可以看到,异常并不在下层filter中处理,而是直接抛给上层,交给MonitorProcessFilter去记录异常,或者直接抛出给调用方。