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,執(zhí)行DubboBeanDefinitionParser的parse方法,通過RootBeanDefinition將serviceBean暴露給spring。(實際調用AutowireCapableBeanFactory.registerBeanDefinition)
1.4 serviceBean實現(xiàn)了BeanNameAware接口,自動注入spring中的單例name。
part -- 服務暴露(生產者)
2.dubbo服務暴露
2.1 serviceBean實現(xiàn)了ApplicationListener,在bean初始化時觸發(fā)onApplicationEvent方法,調用serviceConfig的export方法。
2.2 serviceConfig初始化,先初始化靜態(tài)變量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字節(jié)碼技術生成代理類Protocol$Adpative,ProxyFactory$Adpative。
附上兩個動態(tài)類的源碼。可以看到protocol默認的是dubbo,proxy默認的是javassist。
2.3 export判斷是否需要延遲暴露,執(zhí)行暴露方法doExport()。
2.4 doExport檢查通過,調用doExportUrls
2.5 doExportUrls根據不同的協(xié)議將服務以URL(dubbo)形式暴露。
2.6 如果服務未配置成remote,則本地暴露(exportLocal),如果未配置成local,則注冊服務(registryProtocol)
2.7 exportLocal:生成本地protocol(Constants.LOCAL_PROTOCOL = injvm),
proxyFactory.getInvoker StubProxyFactoryWrapper->JavassistProxyFactory.getInvoker。Wrapper.getWrappery獲取服務的封裝代理類(javassist動態(tài)字節(jié)碼),詳細參照ClassGenerator.toClass。
protocol.export ExtensionLoader.getExtension(injvm)->createExtension -> getExtensionClasses(返回cachedClasses對應的值)
接著循環(huán)cachedWrapperClasses,層層裝飾(裝飾模式),InjvmProtocol,ProtocolFilterWrapper,ProtocolListenerWrapper增強服務。
ProtocolFilterWrapper buildInvokerChain建立了filter鏈,方便開發(fā)者根據業(yè)務進行擴展。
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實現(xiàn)了InitializingBean接口,在afterPropertiesSet后執(zhí)行getObject()方法,調用referenceConfig的init方法。
4.2 StaticContext.getSystemContext()是dubbo全局的線程安全上下文,存放方法調用的相關信息。
4.2 createProxy,設置invoker,這里的invoker有協(xié)議默認的dubbo invoker,cluster invoker(重連機制,默認Failover,重試兩次,一共三次)
返回InvokerInvocationHandler(javassist動態(tài)字節(jié)碼改造后的代理,執(zhí)行方法時,實際執(zhí)行的是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監(jiān)聽器,調用contextInitialized方法,ContextLoder的initWebApplicationContext,createWebApplicationContext默認創(chuàng)建ContextLoader.properties里的XmlWebApplicationContext,強制轉換成configureAndRefreshWebApplicationContext
最終調用AbstractApplicationContext的refresh方法(前面調用了ApplicationContextInitializer的initialize,這里可以做一些spring默認規(guī)則的修改,比如id重復bean處理,spring默認覆蓋)
2.
?
?動態(tài)生成的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?
動態(tài)生成的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×tamp=1457518110700 View Code?
動態(tài)生成的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
總結
- 上一篇: 猎豹MFC--文件对话框CFileDia
- 下一篇: TSQL编程