SOFARPC —— Generic Service (泛化调用) 解析

今晚心情无比激动,多云转晴!原因在于弄懂些 Generic Service 实现原理,很有成就感。

各位看官莫笑,今晚,小小的收获,也是非常满足的。下面进入正题!

一、前言

普遍RPC在客户端需要提供接口,如果不提供则无法进行调用。同时,因为客户端也依赖提供的接口,服务端的升级、优化所带来的更新,客户端也要及时的更新API,否则会带来影响。这样,就带来了依赖接口,常常更新API(接口)的麻烦。为了解决这个问题,需要进行泛化调用。

二、使用

在网上一搜,都是Dubbo的泛化调用的例子,可以很少有讲解它的原理的。也不能为了用个泛化调用,就一定要使用Dubbo吧(个人观点:淘宝内部放弃Dubbo,此外配置繁琐,没有人维护,所以不建议使用)。适合的才是最好的,不能生搬硬套。

我google一下,后来发现sofa-rpc框架,里面有泛化调用(在此推荐大家使用sofa-rpc,具体介绍,自己google),下载源码,debug跟着走几遍,Generic Service 实现原理弄懂了。

demo片段如下(下载sofa-rpc的源码,里面有demo):

 1 ConsumerConfig<GenericService> consumerConfig = new ConsumerConfig<GenericService>()
 2             .setApplication(applicationConfig)
 3             .setInterfaceId(TestGenericService.class.getName())
 4             .setGeneric(true)
 5             .setTimeout(50000)
 6             .setDirectUrl("bolt://127.0.0.1:22222?appName=generic-server");
 7         GenericService testService = consumerConfig.refer();
// 上面这行中,生成GenericService的动态代理类
8 9 LOGGER.warn("started at pid {}", RpcRuntimeContext.PID); 10 11 while (true) { 12 try { 13 String s1 = (String) testService.$invoke("echoStr", new String[] { "java.lang.String" }, 14 new Object[] { "1111" });

(本文只分析泛化调用的部分,其余部分略过)

三、原理

它的原理无非就是将泛化调用转化为普通调用,关键在于对象的表示和序列化。

看一下流程图:

 

首先,Client会通过动态代理创建GenericService的代理类;

然后,会经过一系列过滤链(优先级排序,默认不需要,大的优先级高)

ConsumerExceptionFilter     order = -20000
RpcReferenceContextFilter  order = -19500
ConsumerGenericFilter        order = -18000
ConsumerTracerFilter           order = -10000
ConsumerInvoker           这里会进行真正的业务的调用

在泛化调用过滤器(ConsumerGenericFilter)中,会进行下列操作:

设置序列化工厂类型为普通序列化(序列化反序列化均使用SofaSerializerFactory,值为0),并设置到Request参数中。

★进行调用参数($invoke参数)的修正,变成普通的调用参数(调用方法,调用参数类型,调用参数值)

★设置调用类型

最后,使用SOFABolt协议进行进行网络调用。

-----------------------------------------------------------------------------------

原文地址:https://www.cnblogs.com/lihao007/p/10440577.html