1、啓動
dubbo藉助spring的schemas來啓動(dubbo.jar/META-INF/spring.schemas)。
在dubbo.jar/META-INF/spring.handlers裏配置了dubbo bean的解析類DubboNamespaceHandler。主要的有ServiceBean.java和ReferenceBean.java。html
2、Dubbo Bean的註冊(DubboBeanDefinitionParser.java)
DubboBeanDefinitionParser.parse():將咱們在beans-dubbo.xml裏面配置的 bean 進行解析(包括dubbo的配置,ServiceBean和ReferenceBean),而後註冊到Spring容器中,給Spring託管。
例如:beans-dubbo.xml有以下配置java
<dubbo:application name="#{dubboConfig.applicationName}" owner="#{dubboConfig.applicationOwner}" /> <dubbo:registry address="#{dubboConfig.registryAddress}" /> <dubbo:protocol name="#{dubboConfig.protocolName}" port="#{dubboConfig.protocolPort}" /> <dubbo:provider retries="0" timeout="10000" /> <dubbo:consumer check="false" /> <dubbo:service interface="com.tz.agent.job.IAccountNettingTask" ref="accountNettingTask" /> <dubbo:reference id="accountQueryService" interface="com.basizbiz.account.service.IAccountQueryService"/>
dubbo.properties配置:web
dubbo.application.name=tz-agent dubbo.application.owner=tf dubbo.registry.address=zookeeper://192.168.xx.44:2181 dubbo.protocol.name=dubbo dubbo.protocol.port=20910
容器裏面相關的bean name以下:(parserContext.getRegistry().getBeanDefinitionNames()的結果)redis
accountNettingTask, #{dubboConfig.applicationName}, com.alibaba.dubbo.config.RegistryConfig, #{dubboConfig.protocolName},
com.alibaba.dubbo.config.ProviderConfig, com.alibaba.dubbo.config.ConsumerConfig, com.tz.agent.job.IAccountNettingTask, accountQueryService
1. 第一個accountNettingTask是Spring @Service註解產生的bean。算法
2. com.ihome.tz.agent.job.IAccountNettingTask是dubbo配置文件裏面定義的ServiceBean。spring
3. accountQueryService是dubbo配置文件裏面定義的ReferenceBean。api
能夠看出,Provider端生產了兩種bean,一種是@Service的bean,還有一種是dubbo export的bean。併發
3、Provider端暴露服務
ServiceBean.afterPropertiesSet()方法最終會作服務暴露export();
拼裝dubbo的URL --> protocol.export(invoker) --> ProtocolFilterWrapper.export() --> protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER))
buildInvokerChain()會將知足條件的Filter層層包裝在Invoker上。好比:ExceptionFilter、ValidationFilter、EchoFilter....app
暴露的URL形如:
dubbo://192.168.xx.11:20910/com.tz.agent.job.IHistoryShareInitJob?anyhost=true&application=tz-agent&default.retries=0&default.timeout=10000&dubbo=2.5.3&interface=com.ihome.tz.agent.job.IHistoryShareInitJob&methods=initByExcel&owner=tf&pid=9596&revision=0.0.2-SNAPSHOT&side=provider×tamp=1490688484344負載均衡
4、Consumer端引用服務
ReferenceBean.afterPropertiesSet()方法最終會調ReferenceBean.createProxy()給ref賦值。
proxyFactory.getProxy(invoker) --> JavassistProxyFactory.getProxy()
ref的實例持有一個new InvokerInvocationHandler(invoker)對象。
------------------------
refprotocol.refer() --> ProtocolFilterWrapper.refer() --> buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER)
引用的URL形如:
dubbo://10.166.xx.85:20899/com.biz.product.service.ISharesQueryService?anyhost=true&application=tz-agent&check=false&default.check=false&default.retries=0&default.timeout=10000&dubbo=2.5.3&interface=com.ihome.biz.product.service.ISharesQueryService&methods=queryProduct,queryByDate,queryBenefitAccount,queryProductByBizProductCode,queryBizProductSelect,queryAllProductList,queryProductByBenefitCode,queryBizProductPage&owner=tf&pid=12772&revision=0.0.5-SNAPSHOT&side=consumer×tamp=1490688712775
附:Dubbo SPI :
Dubbo SPI是Dubbo留的擴展點
例如Dubbo的Protocal就是經過dubbo SPI 來擴展的。 ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort()
Dubbo SPI 加載文件
ExtensionLoader.loadFile(extensionClasses, DUBBO_INTERNAL_DIRECTORY);
ExtensionLoader.loadFile(extensionClasses, DUBBO_DIRECTORY);
ExtensionLoader.loadFile(extensionClasses, SERVICES_DIRECTORY);
【1】
dubbo-2.5.3.jar\META-INF\dubbo\internal\com.alibaba.dubbo.common.extension.ExtensionFactory
adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory spring=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
針對文件中的類:
帶有@Adaptive 的放到 cachedAdaptiveClass 中,有參數爲ExtensionFactory的構造函數的放到 cachedWrapperClasses 中,不然放到 cachedClasses 中
-->
public T getAdaptiveExtension() 優先取 cachedAdaptiveClass.newInstance(),即 AdaptiveExtensionFactory
不然,會動態編譯代碼 String code = createAdaptiveExtensionClassCode();,使用AdaptiveExtensionFactory.getExtension(Class<T> type, String name)拿到適配的Extension
【2】
dubbo-2.5.3.jar\META-INF\dubbo\internal\com.alibaba.dubbo.rpc.Protocol
======================
registry=com.alibaba.dubbo.registry.integration.RegistryProtocol --- 放到 cachedClasses
filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper --- 放到 cachedWrapperClasses (ref時將Filter裝飾在)
listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper --- 放到 cachedWrapperClasses
mock=com.alibaba.dubbo.rpc.support.MockProtocol
injvm=com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol --- 放到 cachedClasses
dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol --- 放到 cachedClasses
rmi=com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocol --- 放到 cachedClasses
hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol --- 放到 cachedClasses
com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
com.alibaba.dubbo.rpc.protocol.webservice.WebServiceProtocol
thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocol
memcached=memcom.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocol
redis=com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol
======================
Dubbo中的特性和坑:
1. Dubbo的異步具備傳遞性。(移除異步:RpcContext.getContext().getAttachments().remove(com.alibaba.dubbo.common.Constants.ASYNC_KEY);)
3. Dubbo 支持 telnet
4. Dubbo 支持泛化調用
Dubbo配置:
注意:
dubbo中全部配置項分爲三大類:
1. 【服務發現】參數:表示該配置項用於服務的註冊與發現,目的是讓消費方找到提供方。
2. 【服務治理】參數:表示該配置項用於治理服務間的關係,或爲開發測試提供便利條件。
3. 【性能調優】參數:表示該配置項用於調優性能,不一樣的選項對性能會產生影響。
只有interface,group,version是服務的匹配條件,用於服務發現,三者決定是否是同一個服務,其它配置項均爲服務調優和服務治理參數。
http://dubbo.io/user-guide/reference-xmlconf/introduction.html
緣由以下:
不然,Consumer會使用Consumer端的全局設置,這對於Provider不可控的,而且每每是不合理的。
配置的覆蓋規則:
1) 方法級配置別優於接口級別,即小Scope優先
2) Consumer端配置 優於 Provider配置 優於 全局配置,最後是Dubbo Hard Code的配置值(見配置文檔)
Provider上儘可能多配置Consumer端的屬性,讓Provider實現者一開始就思考Provider服務特色、服務質量的問題。
示例:
<
dubbo:service
interface
=
"com.alibaba.hello.api.HelloService"
version
=
"1.0.0"
ref
=
"helloService"
timeout
=
"300"
retry
=
"2"
loadbalance
=
"random"
actives
=
"0"
/>
<
dubbo:service
interface
=
"com.alibaba.hello.api.WorldService"
version
=
"1.0.0"
ref
=
"helloService"
timeout
=
"300"
retry
=
"2"
loadbalance
=
"random"
actives
=
"0"
>
<
dubbo:method
name
=
"findAllPerson"
timeout
=
"10000"
retries
=
"9"
loadbalance
=
"leastactive"
actives
=
"5"
/>
<
dubbo:service
/>
|
在Provider能夠配置的Consumer端屬性有: