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…

matplotlib的colorbar自定义刻度范围

如以下程序将colorbar的范围从0-1变为0-10 import matplotlib.ticker as tickerdef fmt1(x,pos): # 设置colorbar的刻度值return int(x*10)fig plt.figure() ax fig.gca() im ax.imshow(np.random.random([10, 10])) plt.colorbar(im, fraction0.03, pad0.05, formattick…

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;不知道学习的并发知识如何运用到实际项目…

7.python xmlrpclib及allownone作用

__author__ Administrator from xmlrpclib import ServerProxy connServerProxy("http://192.168.8.137:2003") aconn.black_remove("192.168.12.187") bconn.commit_now() print a xmlrpc是基于http协议的远程函数调用&#xff0c;xmlrpc中具有一个你常…

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;我的电脑数据存放的默认路径为…

python中def main是什么意思_关于python:为什么使用def main()?

本问题已经有最佳答案&#xff0c;请猛点这里访问。 Possible Duplicate: What does if __name__"__main__" do? 我看过一些代码示例和教程 1 2 3 4 5def main(): # my code here if __name__ "__main__": main() 但是为什么呢&#xff1f;有没有什么理由…

华为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;但是在实际开发中…

python将数据写入Excel

import xlsxwriter workbook xlsxwriter.Workbook(D:\data.xlsx, {nan_inf_to_errors: True}) #创建一个Excel文件 worksheet workbook.add_worksheet() #创建一个sheettitle [U1,U2,U3,U4,U5,U6,U7,U8,U9,U10] #表格title worksheet.write_row(A1,title…

python脚本编程实例_从零学python系列之数据处理编程实例(一)

要求&#xff1a;分别以james&#xff0c;julie&#xff0c;mikey&#xff0c;sarah四个学生的名字建立文本文件&#xff0c;分别存储各自的成绩&#xff0c;时间格式都精确为分秒&#xff0c;时间越短成绩越好&#xff0c;分别输出每个学生的无重复的前三个最好成绩&#xff0…

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

来源&#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;其数字孪生体都可以复制。在未来的医疗领域&…

BZOJ2732: [HNOI2012]射箭

列出不等式&#xff0c;二分&#xff0c;半平面交判定。注意可行域可能为点或线段或无界区域。坐标范围略大&#xff0c;算出来a的范围约为-1e9~-1e-18&#xff08;a<0&#xff09;&#xff0c;理论上要用long double&#xff0c;不过好像double也能过。 #include<algori…

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版本下载 下…