dubbo工作原理

part -- 外挂
1.dubbo借助spring的schema启动和初始化
1.1 spring扫描所有jar下META-INF的spring.handlers和spring.schemas。
1.2 运行spring.handlers下定义的DubboNamespaceHandler的init方法。
1.3 spring加载xml,执行DubboBeanDefinitionParser的parse方法,通过RootBeanDefinition将serviceBean暴露给spring。(实际调用AutowireCapableBeanFactory.registerBeanDefinition)
1.4 serviceBean实现了BeanNameAware接口,自动注入spring中的单例name。

part -- 服务暴露(生产者)
2.dubbo服务暴露
2.1 serviceBean实现了ApplicationListener,在bean初始化时触发onApplicationEvent方法,调用serviceConfig的export方法。
2.2 serviceConfig初始化,先初始化静态变量protocol和proxyFactory。
getExtensionLoader.getExtensionLoader ->getAdaptiveExtension->createAdaptiveExtension->getAdaptiveExtensionClass->getExtensionClasses->loadExtensionClasses
->loadFile->createAdaptiveExtensionClassCode
loadFile采用的是java spi的思想,分别读取META-INF/services/,META-INF/dubbo/,META-INF/dubbo/internal/下文件进行解析。
以protocol为例,其中ProtocolFilterWrapper和ProtocolListenerWrapper是有参数为protocol构造函数的,被放到Set<Class<?>> cachedWrapperClasses(后面会用到)中。
没有protocol构造函数,但是有@Adaptive注解的,被放到Holder<Object> cachedAdaptiveInstance中。
以上都不满足的放到cachedClasses中。
createAdaptiveExtensionClassCode通过javassist字节码技术生成代理类Protocol$Adpative,ProxyFactory$Adpative。
附上两个动态类的源码。可以看到protocol默认的是dubbo,proxy默认的是javassist。
2.3 export判断是否需要延迟暴露,执行暴露方法doExport()。
2.4 doExport检查通过,调用doExportUrls
2.5 doExportUrls根据不同的协议将服务以URL(dubbo)形式暴露。
2.6 如果服务未配置成remote,则本地暴露(exportLocal),如果未配置成local,则注册服务(registryProtocol)
2.7 exportLocal:生成本地protocol(Constants.LOCAL_PROTOCOL = injvm),
proxyFactory.getInvoker StubProxyFactoryWrapper->JavassistProxyFactory.getInvoker。Wrapper.getWrappery获取服务的封装代理类(javassist动态字节码),详细参照ClassGenerator.toClass。
protocol.export ExtensionLoader.getExtension(injvm)->createExtension -> getExtensionClasses(返回cachedClasses对应的值)
接着循环cachedWrapperClasses,层层装饰(装饰模式),InjvmProtocol,ProtocolFilterWrapper,ProtocolListenerWrapper增强服务。
ProtocolFilterWrapper buildInvokerChain建立了filter链,方便开发者根据业务进行扩展。
registryProtocol export ->ProtocolFilterWrapper export-> ProtocolListenerWrapper export->dubboProtocol export。

3.netty启动
3.1 openServer netty server打开侦听服务,并缓存服务。
dubbo -> export() -> openServer() -> createServer() -> Exchangers.bind()(HeaderExchanger) -> NettyTransporter -> NettyServer.open()(编码解码采用exchange)
netty ChannelFactory(boss worker) ChannelPipeline(责任链模式) ChannelHandler(处理器) --- 反应器模式

part -- 服务引用(消费者)
4.dubbo服务引用
4.1 referenceBean实现了InitializingBean接口,在afterPropertiesSet后执行getObject()方法,调用referenceConfig的init方法。
4.2 StaticContext.getSystemContext()是dubbo全局的线程安全上下文,存放方法调用的相关信息。
4.2 createProxy,设置invoker,这里的invoker有协议默认的dubbo invoker,cluster invoker(重连机制,默认Failover,重试两次,一共三次)
返回InvokerInvocationHandler(javassist动态字节码改造后的代理,执行方法时,实际执行的是invoker的doinvoke方法)
cluster invoker的doinvoke方法会调用select(),负载均衡,默认RandomLoadBalance
4.3 获取dubbo invoker时,调用dubbo的refer,调用getClients获取ExchangeClient,默认的ExchangeClient是共享的getSharedClient。initClient默认是非延迟的,调用Exchangers.connect,最终调用HeaderExchanger.connect,调用
Transporters.connect,同生产者一样,默认的Transporters是netty。因此最终的ExchangeClient是NettyClient。
4.3 dubbo invoker doinvoke方法,ExchangeClient.request方法,结果通过future的get方法返回,get方法通过lock+while+超时控制。
4.4 ExchageClient.request最终调用的是nettyChannel
1.NettyHandler.messageReceived(ChannelHandlerContext ctx, MessageEvent e)
2.AbstractPeer.received(Channel ch, Object msg)
3.MultiMessageHandler.received(Channel channel, Object message)
4.AllChannelHandler.received(Channel channel, Object message)
5.DecodeHandler.received(Channel channel, Object message)
6.HeaderExchangeHandler.received(Channel channel, Object message)
7.DefaultFuture.received(Channel channel, Response response) //注意是static方法
DefaultFuture future = FUTURES.remove(response.getId());
if (future != null) {
future.doReceived(response);
}

http://blog.csdn.net/a19881029/article/details/51058428

spring
1. 入口ContextLoaderListener监听器,调用contextInitialized方法,ContextLoder的initWebApplicationContext,createWebApplicationContext默认创建ContextLoader.properties里的XmlWebApplicationContext,强制转换成configureAndRefreshWebApplicationContext
最终调用AbstractApplicationContext的refresh方法(前面调用了ApplicationContextInitializer的initialize,这里可以做一些spring默认规则的修改,比如id重复bean处理,spring默认覆盖)
2.

 

 动态生成的Protocol$Adpative.class

package com.alibaba.dubbo.rpc;import com.alibaba.dubbo.common.extension.ExtensionLoader;public class Protocol$Adpative implements com.alibaba.dubbo.rpc.Protocol {public void destroy() {throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");}public int getDefaultPort() {throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");}public com.alibaba.dubbo.rpc.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1)throws java.lang.Class {if (arg1 == null)throw new IllegalArgumentException("url == null");com.alibaba.dubbo.common.URL url = arg1;String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());if (extName == null)throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url("+ url.toString() + ") use keys([protocol])");com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);return extension.refer(arg0, arg1);}public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0)throws com.alibaba.dubbo.rpc.Invoker {if (arg0 == null)throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");if (arg0.getUrl() == null)throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");com.alibaba.dubbo.common.URL url = arg0.getUrl();String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());if (extName == null)throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url("+ url.toString() + ") use keys([protocol])");com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);return extension.export(arg0);}
}
View Code

 

动态生成的ProxyFactory$Adpative.class

package com.alibaba.dubbo.rpc;import com.alibaba.dubbo.common.extension.ExtensionLoader;public class ProxyFactory$Adpative implements com.alibaba.dubbo.rpc.ProxyFactory {public java.lang.Object getProxy(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.Invoker {if (arg0 == null)throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");if (arg0.getUrl() == null)throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");com.alibaba.dubbo.common.URL url = arg0.getUrl();String extName = url.getParameter("proxy", "javassist");if (extName == null)throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url("+ url.toString() + ") use keys([proxy])");com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);return extension.getProxy(arg0);}public com.alibaba.dubbo.rpc.Invoker getInvoker(java.lang.Object arg0, java.lang.Class arg1,com.alibaba.dubbo.common.URL arg2) throws java.lang.Object {if (arg2 == null)throw new IllegalArgumentException("url == null");com.alibaba.dubbo.common.URL url = arg2;String extName = url.getParameter("proxy", "javassist");if (extName == null)throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url("+ url.toString() + ") use keys([proxy])");com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);return extension.getInvoker(arg0, arg1, arg2);}
}{class com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@5d1275be, class com.alibaba.dubbo.common.compiler.support.JavassistCompiler=com.alibaba.dubbo.common.compiler.support.JavassistCompiler@66f03cae, class com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory@261ff84e}injvm://127.0.0.1/com.ihome.tf.order.service.IBenefitFoundService?anyhost=true&application=tf-order&default.retries=0&default.timeout=10000&dubbo=2.5.3&interface=com.ihome.tf.order.service.IBenefitFoundService&methods=update,clear,qryBenefitFndOrderList,qryCheckPassedBenefitList,qryBenefitFoundOrderSumInf,verify,qryBenefitFound&owner=tf&pid=1492&revision=0.0.1-SNAPSHOT&side=provider&timestamp=1457518110700
View Code

 

动态生成的Wrapper1.class

package com.alibaba.dubbo.common.bytecode;import com.prepay.dto.ShareRulesReq;
import com.prepay.service.IOutShareService;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;public class Wrapper1 extends Wrapperimplements ClassGenerator.DC
{public static String[] pns;public static Map pts;public static String[] mns;public static String[] dmns;public static Class[] mts0;public static Class[] mts1;public static Class[] mts2;public String[] getPropertyNames(){return pns;}public boolean hasProperty(String paramString){return jdField_pts_of_type_JavaUtilMap.containsKey(paramString);}public Class getPropertyType(String paramString){return (Class)jdField_pts_of_type_JavaUtilMap.get(paramString);}public String[] getMethodNames(){return mns;}public String[] getDeclaredMethodNames(){return dmns;}public void setPropertyValue(Object paramObject1, String paramString, Object paramObject2){try{IOutShareService localIOutShareService = (IOutShareService)paramObject1;}catch (Throwable localThrowable){throw new IllegalArgumentException(localThrowable);}throw new NoSuchPropertyException("Not found property \"" + paramString + "\" filed or setter method in class com.ihome.prepay.service.IOutShareService.");}public Object getPropertyValue(Object paramObject, String paramString){try{IOutShareService localIOutShareService = (IOutShareService)paramObject;}catch (Throwable localThrowable){throw new IllegalArgumentException(localThrowable);}throw new NoSuchPropertyException("Not found property \"" + paramString + "\" filed or setter method in class com.ihome.prepay.service.IOutShareService.");}public Object invokeMethod(Object paramObject, String paramString, Class[] paramArrayOfClass, Object[] paramArrayOfObject)throws InvocationTargetException{IOutShareService localIOutShareService;try{localIOutShareService = (IOutShareService)paramObject;}catch (Throwable localThrowable1){throw new IllegalArgumentException(localThrowable1);}try{if ((!"queryShareRuleDetail".equals(paramString)) || (paramArrayOfClass.length == 1))return localIOutShareService.queryShareRuleDetail((String)paramArrayOfObject[0]);if ((!"queryShareRuleList".equals(paramString)) || (paramArrayOfClass.length == 1))return localIOutShareService.queryShareRuleList((ShareRulesReq)paramArrayOfObject[0]);if ((!"querySharePullDownList".equals(paramString)) || (paramArrayOfClass.length == 0))return localIOutShareService.querySharePullDownList();}catch (Throwable localThrowable2){throw new InvocationTargetException(localThrowable2);}throw new NoSuchMethodException("Not found method \"" + paramString + "\" in class com.ihome.prepay.service.IOutShareService.");}
}
View Code

 

 

<以上内容由同事提供>

转载于:https://www.cnblogs.com/kevin-yuan/p/5531261.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/490651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

问题:AttributeError: 'Tensor' object has no attribute 'creator'

AttributeError: Tensor object has no attribute creator 根据pytorch官方文档的说法&#xff0c;变量具有如上的三个属性&#xff0c;在获取y操作的creator属性时&#xff0c;却出现没有该属性的错误。 import torch from torch.autograd import Variable x Variable(torch…

ACL 2019年度回顾:自然语言处理发展趋势

大数据文摘出品来源&#xff1a;mihaileric编译&#xff1a;赵伟、邢畅、张秋玥今年7月底&#xff0c;计算语言学协会年会&#xff08;ACL&#xff09;在风景优美的佛罗伦萨召开。会场设在了一座古老的Medici家族的城堡中。作为NLP研究最大规模的会议之一&#xff0c;ACL 2019的…

Python基础:获取迭代器下一项目的常见操作

目录 获取迭代器下一项目通常有三种方法 python3中最常见的一种错误使用 获取迭代器下一项目通常有三种方法 next()函数iterator.__next__()属性for循环 next()函数 iterator iter([1,2,3,4,5,6]) a next(iterator) print(a) b next(iterator) print(b) 输出&#xff1…

电商项目的并发量一般是多少_掌握这些,高并发秒杀系统就不用担心了!

很多小伙伴反馈说&#xff0c;高并发专题学了那么久&#xff0c;但是&#xff0c;在真正做项目时&#xff0c;仍然不知道如何下手处理高并发业务场景!图片来自 Pexels甚至很多小伙伴仍然停留在只是简单的提供接口(CRUD)阶段&#xff0c;不知道学习的并发知识如何运用到实际项目…

matplotlib的colorbar设置显示的刻度个数和指定的刻度值

通过matplotlib.ticker.MaxNLocator(nbinsn)来设置colorbar上的刻度值个数 import matplotlib.ticker as ticker fig plt.figure() ax fig.gca() im ax.imshow(np.random.random([10, 10])) cb1 plt.colorbar(im, fraction0.03, pad0.05) tick_locator ticker.MaxNLocato…

Windows下MySQL数据库更改数据存储位置

Windows下MySQL数据库更改数据存储位置 1、创建一个新的存储数据文件 比如&#xff0c;我创建了一个文件 E:\MySQL_Service &#xff0c;用来放mysql数据。 2、找到配置文件my.ini和mysql原本数据存放位置 之前用的是默认安装位置&#xff0c;我的电脑数据存放的默认路径为…

华为5G手机芯片被唱衰:美研究机构拆解6款量产机,不谈能力对标高通骁龙X50...

来源&#xff1a;凹非寺全球5G手机芯片到底哪家强&#xff1f;能力上来看&#xff0c;量产的华为巴龙5000参数超过骁龙X50&#xff0c;但最近英国研究机构IHS Markit拆解6款5G手机后给出另一面结论&#xff1a;华为手机5G&#xff0c;没高通骁龙有竞争力。IHS的结论&#xff0c…

CSS3-06 样式 5

浮动&#xff08;Float&#xff09; 关于浮动&#xff0c;要说的可能就是&#xff1a;一个设置了浮动的元素会尽量向左移动或向右移动&#xff0c;且会对其后的元素造成影响&#xff0c;其后的元素会排列在其围绕在其左下或右下部。似乎就这么简单&#xff0c;但是在实际开发中…

量子纠缠为什么不能用于瞬时通讯?

来源&#xff1a;数学职业家什么是信息&#xff1f; 信息的一个比较被认可的定义是1948年数学家香农在论文中提出的&#xff1a;信息是用来消除随机不定性的东西。比如&#xff0c;盒子里有一个硬币&#xff0c;它可以是正面向上&#xff0c;也可以是反面向上&#xff0c;在打开…

第二次冲刺每日站立会议03

会议照片&#xff1a; 会议内容&#xff1a; 祖浩然&#xff1a; 昨天&#xff1a;学习要进行优化的相关知识 今天&#xff1a;对前两个界面进行界面的修改 遇到的问题&#xff1a;设置背景图片之后按钮无法显示 刘洋&#xff1a; 昨天&#xff1a;学习要进行优化的相关知识 今…

cad菜单栏快捷键_天正建筑菜单栏不见了怎么调出来

在使用天正建筑得出时候&#xff0c;可能会因为不小心&#xff0c;把菜单栏关闭了&#xff0c;却一时不知道怎样打开&#xff0c;下面使用三种方式&#xff0c;教你将不见了的菜单栏调出来。方法一&#xff1a;使用键盘快捷键1.在界面中&#xff0c;我们可以看到&#xff0c;这…

图说报告 | “智能+”的终极版图:数字孪生世界

来源&#xff1a;阿里研究院数字孪生&#xff08;Digital Twin&#xff09;是近几年兴起的非常前沿的新技术&#xff0c;进入Gartner2019年十大战略技术趋势行列。今天&#xff0c;从300万个波音777零部件到人类心脏&#xff0c;其数字孪生体都可以复制。在未来的医疗领域&…

MATLAB画频率响应曲线(幅频特性和相频特性)并将横坐标转换为赫兹hz单位

matlab画频率响应曲线的函数为&#xff1a; [h,w] freqz(b,a,n) b,a&#xff1a;传递函数系数 h&#xff1a;频率响应 w&#xff1a;角频率&#xff0c;0~π 更多参数解释参考官方链接https://ww2.mathworks.cn/help/signal/ref/freqz.html?requesteddomaintrue 用freqz…

python3.6配置环境变量_python安裝及环境变量配置

一、安装 1.python下载 进入官网后选择download&#xff0c;选择windows进入如下页面1.1 python3.6.6版本下载 首先我们下载python3.6.6版本&#xff0c;下滑页面找到此位置&#xff0c;64位系统选择红色框框&#xff0c;32位选择蓝色框框点击进行下载 1.2 python2.7版本下载 下…

人与动物之间有没有一条不可逾越的鸿沟?——从基础存在论到生命哲学

来源&#xff1a;《哲学动态》 2018年第12期作者&#xff1a;舒红跃&#xff08;湖北大学哲学学院&#xff09;张哲&#xff08;湖北省道德与文明研究中心&#xff09;海德格尔《存在与时间》中对“此在”的生存论刻画是哲学史中的经典&#xff0c;此在“在-世界中-存在”是存在…

matlab显示曲线图中某个点的坐标值

在画好一幅曲线图后&#xff0c;有时候我们需要找出某个坐标的点&#xff0c;可以通过打开数据游标功能&#xff0c;此时鼠标点击的位置就会显示出坐标值&#xff0c;如下图&#xff1a; 此时保存下来的图也会带有显示的坐标值。 如果需要显示多个坐标的值&#xff0c;按住alt…

数字滤波器的差分方程和传递函数

差分方程用于描述线性、时不变、因果滤波器 数字滤波器的差分方程表示为&#xff1a; 对应的系统函数/传递函数为&#xff1a; a_k&#xff0c;b_k为滤波器系数 当a_k0时&#xff0c;滤波器当前的输出仅依赖于输入&#xff0c;而不依赖过去的输出&#xff0c;称为非递归滤波器…

2019年AI实力对决:美国领跑,中国追赶,欧盟弱势

来源&#xff1a; 智东西&#xff0c;Data Innovation美国当地时间8月18日&#xff0c;美国数据创新中心&#xff08;Center for Data Innovation&#xff09;发布针对中国、美国和欧洲三大地区的人工智能发展报告&#xff0c;报告显示&#xff0c;目前美国在AI发展中仍然保持领…

谷歌学术搜索技巧:查找一个句子的某个空应该用什么词

在写论文的时候经常遇到某个地方不知道应该用什么词比较专业的问题&#xff0c;举个例子&#xff1a; we used training strategy * in literature [10] *号处应该填什么词比较专业呢 这时可以在谷歌学术找到答案 在谷歌学术搜索中输入&#xff1a; "training strate…

关于未来的蝴蝶效应,《崛起的超级智能》创作有感

来源&#xff1a;刘锋科学网博客前言&#xff1a;2019年7月5日&#xff0c;当我拿到出版社寄出的《崛起的超级智能&#xff1a;互联网大脑如何影响科技未来》时&#xff0c;仿佛在捧着一个刚出生的婴儿。不是十月怀胎&#xff0c;而是历经12年的孕育&#xff0c;2年多的艰苦生产…