我们姑且称服务请求的发起者为客户端,那么客户端为了发出请求,
首先需要获取该服务对象,通过ServiceFactory类中的getService方法可以获取某个服务对象。其中该方法需要传入一个invokerconfig的对象,主要是一些配置参数。getService主要做了两件事情,第一个是获取之前provider在zk上注册的数据,第二个是利用jdk proxy获得服务接口代理类。
public Object proxyRequest(InvokerConfig<?> invokerConfig) throws SerializationException {
return Proxy.newProxyInstance(ClassUtils.getCurrentClassLoader(invokerConfig.getClassLoader()),
new Class[] { invokerConfig.getServiceInterface() }, new ServiceInvocationProxy(invokerConfig,
InvokerProcessHandlerFactory.selectInvocationHandler(invokerConfig)));
}
以上就是利用jdk proxy来生成代理类的过程,后面请求的分析当然也是从这里开始。
当然还有一大堆初始化的事情,
if (!isStartup) {
ServiceInvocationRepository.getInstance().init();
InvokerProcessHandlerFactory.init();
SerializerFactory.init();
LoadBalanceManager.init();
RegionPolicyManager.INSTANCE.init();
Monitor monitor = MonitorLoader.getMonitor();
if (monitor != null) {
monitor.init();
}
ResponseProcessorFactory.selectProcessor().getResponseProcessThreadPool().prestartAllCoreThreads();
isStartup = true;
logger.warn("pigeon client[version:" + VersionUtils.VERSION + "] has been started");
}
分别会初始化服务仓库、process组件、序列化组件、负载均衡组件、区域策略、监控相关和响应处理器。这些部分会在之后一一叙述。
利用spring的ioc,很容易将这些proxy作为bean注册到容器中,以便后面方便调用。
接下来当客户端发出请求后,根据JDK Proxy的实现,就会调用ServiceInvocationHandler类的handle方法,而proxy中的handler又是通过InvokerProcessHandlerFactory类来初始化的,看看工厂类的init方法,
public static void init() {
if (!isInitialized) {
if (Constants.MONITOR_ENABLE) {
registerBizProcessFilter(new RemoteCallMonitorInvokeFilter());
}
registerBizProcessFilter(new TraceFilter());
registerBizProcessFilter(new DegradationFilter());
registerBizProcessFilter(new ClusterInvokeFilter());
registerBizProcessFilter(new GatewayInvokeFilter());
registerBizProcessFilter(new ContextPrepareInvokeFilter());
registerBizProcessFilter(new SecurityFilter());
registerBizProcessFilter(new RemoteCallInvokeFilter());
bizInvocationHandler = createInvocationHandler(bizProcessFilters);
isInitialized = true;
}
}
这一点设计上利用了chain-filter的模式,进行链式处理。其中TraceFilter是进行监控的一些处理,DegradationFilter是用于降级,ClusterInvokeFilter是用来处理集群中的调用方式,GatewayInvokeFilter是获取具体的服务者,ContextPrepareInvokeFilter组要是处理了一些请求参数相关的东西,SecurityFilter是安全相关的事情,而RemoteCallInvokeFilter是进行真正的服务调用。
这里主要关注下RemoteCallInvokeFilter里面做了些什么。
Pigeon的请求目前分为四种模式, SYNC、CALLBACK、FUTURE和ONEWAY。SYNC就是指同步返回请求结果;CALLBACK是指有返回后会自动调用客户端传进来的CALLBACK对象,其实就是回调模式;FUTURE和JDK中的FUTURE概念基本一致,会先返回FUTURE这个占位符,然后客户端可以利用这个占位符来获得结果;ONEWAY的意思就是一去不复返,表示客户端并不关心服务端响应的结果。
具体执行的过程也很简单,pigeon会将参数序列化后,利用netty的方法直接把数据write出去,然后应答回来后,按照不同的模式返回给客户端,当然这些过程都是异步的。