springboot结合dubbo的泛化调用原理
原创
©著作权归作者所有:来自51CTO博客作者liuzhebaba的原创作品,请联系作者获取转载授权,否则将追究法律责任
关于dubbo的泛化调用,很多人都用过,今天我们从原理层面说下dubbo的泛化调用。此文适合有一定dubbo源码基础的人,如果没有的话,先去熟悉下再来看此篇文章
一、使用
关于dubbo泛化调用的使用方式如下:
public Object genericInvoke(String interfaceClass, String methodName, List<Map<String, Object>> parameters){
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
reference.setApplication(application);
reference.setRegistry(registry);
reference.setInterface(interfaceClass); // 接口名
reference.setGeneric(true); // 声明为泛化接口
reference.setVersion("1.0.0");
// reference.setCheck(false);
//ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,
//需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。
//API方式编程时,容易忽略此问题。
//这里使用dubbo内置的简单缓存工具类进行缓存
// ReferenceConfigCache cache = ReferenceConfigCache.getCache();
// GenericService genericService = cache.get(reference);
GenericService genericService = reference.get();
// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
int len = parameters.size();
String[] invokeParamTyeps = new String[len];
Object[] invokeParams = new Object[len];
for(int i = 0; i < len; i++){
invokeParamTyeps[i] = parameters.get(i).get("ParamType") + "";
invokeParams[i] = parameters.get(i).get("Object");
}
return genericService.$invoke(methodName, invokeParamTyeps, invokeParams);
}
上面的方法就是
1.通过registryConfig和applicationConfig生成RefrenceConfig。
2.通过refrenceConfig的get()方法获取GenericService。
3.通过genericService的$invoke方法去调用dubbo。
二、遇到的问题
有些人遇到问题可能就是在获取GenericService这一步。
GenericService genericService = reference.get();
要么获取不到,要么获取超时。我们一步步跟这源码看下
三、源码解析
在get()方法中,会通过ReferenceConfig中的CreateProxy方法中的refer方法去获取引用:
invoker = refprotocol.refer(interfaceClass, urls.get(0));
refer方法获取真正的执行类
在refer方法中,获取真正的执行类,refprotocol是通过ExtensionLoader获取的,你可以声明自己的,一般用默认的就可以。默认的会走到RegistryProtocol的doRefer方法。然后通过RegistryDiretory的subscribe方法进行注册并在之后通过其refreshInvoker方法刷新提供者。所以ReferenceConfig中包含提供者的路由信息。如果最后找不到泛化调用的GenericService都是因为匹配提供者失败造成的,沿着这块代码去寻找一般都可以找到错误原因。
下面一张序列图,简略流程:
ReferenceConfig
RegistryProtocol
RegistryDirectory
get(),createProxy()
refer()
subscribe()
refreshInvoker()
ReferenceConfig
RegistryProtocol
RegistryDirectory