RPC框架Pigeon简析(三)-- 客户端进行服务请求

我们姑且称服务请求的发起者为客户端,那么客户端为了发出请求,
首先需要获取该服务对象,通过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出去,然后应答回来后,按照不同的模式返回给客户端,当然这些过程都是异步的。

    原文作者:FutureTech
    原文地址: https://www.jianshu.com/p/168fca0bf173
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞