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端属性有: