一、启动
dubbo借助spring的schemas来启动(dubbo.jar/META-INF/spring.schemas)。
在dubbo.jar/META-INF/spring.handlers里配置了dubbo bean的解析类DubboNamespaceHandler。主要的有ServiceBean.java和ReferenceBean.java。

二、Dubbo Bean的注册(DubboBeanDefinitionParser.java)
DubboBeanDefinitionParser.parse():将我们在beans-dubbo.xml里面配置的 bean 进行解析(包括dubbo的配置,ServiceBean和ReferenceBean),然后注册到Spring容器中,给Spring托管。
例如:beans-dubbo.xml有如下配置

<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配置:

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()的结果)

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。

3. accountQueryService是dubbo配置文件里面定义的ReferenceBean。

可以看出,Provider端生产了两种bean,一种是@Service的bean,还有一种是dubbo export的bean。

三、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....

暴露的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&timestamp=1490688484344

四、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&timestamp=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);)

2. Dubbo Hessian序列化问题 参数为null

3. Dubbo 支持 telnet

4. Dubbo 支持泛化调用

Dubbo配置:

注意:
dubbo中所有配置项分为三大类:
1. 【服务发现】参数:表示该配置项用于服务的注册与发现,目的是让消费方找到提供方。
2. 【服务治理】参数:表示该配置项用于治理服务间的关系,或为开发测试提供便利条件。
3. 【性能调优】参数:表示该配置项用于调优性能,不同的选项对性能会产生影响。

只有interface,group,version是服务的匹配条件,用于服务发现,三者决定是不是同一个服务,其它配置项均为服务调优和服务治理参数。

http://dubbo.io/user-guide/reference-xmlconf/introduction.html

配置推荐用法

在Provider上尽量多配置Consumer端属性

原因如下:

  1. 作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等
  2. 在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可以作为Consumer的缺省值。

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

    1. timeout,方法调用超时
    2. retries,失败重试次数,缺省是2(表示加上第一次调用,会调用3次)
    3. loadbalance,负载均衡算法(有多个Provider时,如何挑选Provider调用),缺省是随机(random)。
      还可以有轮训(roundrobin)、最不活跃优先(leastactive,指从Consumer端并发调用最好的Provider,可以减少的反应慢的Provider的调用,因为反应更容易累积并发的调用)
    4. actives,消费者端,最大并发调用限制,即当Consumer对一个服务的并发调用到上限后,新调用会Wait直到超时。
      在方法上配置(dubbo:method )则并发限制针对方法,在接口上配置(dubbo:service),则并发限制针对服务。
如果想了解更多Dubbo源码的知识,请移步 Dubbo源码解读——通向高手之路 的视频讲解:
http://edu.51cto.com/sd/2e565

Dubbo原码解析(version:2.5.3)的更多相关文章

  1. dubbo源码解析五 --- 集群容错架构设计与原理分析

    欢迎来我的 Star Followers 后期后继续更新Dubbo别的文章 Dubbo 源码分析系列之一环境搭建 博客园 Dubbo 入门之二 --- 项目结构解析 博客园 Dubbo 源码分析系列之 ...

  2. Dubbo 源码解析四 —— 负载均衡LoadBalance

    欢迎来我的 Star Followers 后期后继续更新Dubbo别的文章 Dubbo 源码分析系列之一环境搭建 Dubbo 入门之二 --- 项目结构解析 Dubbo 源码分析系列之三 -- 架构原 ...

  3. dubbo源码解析-spi(4)

    前言 本篇是spi的第四篇,本篇讲解的是spi中增加的AOP,还是和上一篇一样,我们先从大家熟悉的spring引出AOP. AOP是老生常谈的话题了,思想都不会是一蹴而就的.比如架构设计从All in ...

  4. dubbo源码解析-spi(3)

    前言 在上一篇的末尾,我们提到了dubbo的spi中增加了IoC和AOP的功能.那么本篇就讲一下这个增加的IoC,spi部分预计会有四篇,因为这东西实在是太重要了.温故而知新,我们先来回顾一下,我们之 ...

  5. dubbo源码解析-spi(一)

    前言 虽然标题是dubbo源码解析,但是本篇并不会出现dubbo的源码,本篇和之前的dubbo源码解析-简单原理.与spring融合一样,为dubbo源码解析专题的知识预热篇. 插播面试题 你是否了解 ...

  6. dubbo源码解析-zookeeper创建节点

    前言 在之前dubbo源码解析-本地暴露中的前言部分提到了两道高频的面试题,其中一道dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者还能通信吗?在上周的dubbo源码 ...

  7. 【Dubbo 源码解析】05_Dubbo 服务发现&引用

    Dubbo 服务发现&引用 Dubbo 引用的服务消费者最终会构造成一个 Spring 的 Bean,具体是通过 ReferenceBean 来实现的.它是一个 FactoryBean,所有的 ...

  8. 【Dubbo 源码解析】04_Dubbo 服务注册&暴露

    Dubbo 服务注册&暴露 Dubbo 服务暴露过程是通过 com.alibaba.dubbo.config.spring.ServiceBean 来实现的.Spring 容器 refresh ...

  9. 2、Dubbo源码解析--服务发布原理(Netty服务暴露)

    一.服务发布 - 原理: 首先看Dubbo日志,截取重要部分: 1)暴露本地服务 Export dubbo service com.alibaba.dubbo.demo.DemoService to ...

随机推荐

  1. filter和map的区别

    filter和map初一看很像 都是filter(func,iterable) map(func,iterable) 实际情况是filter函数:filter()为已知的序列的每个元素调用给定的布尔函 ...

  2. 多变量频率统计——r

    例如有X1,X2,..,Xn个变量,我需要对每一个变量进行频次统计,如果一个一个求解的话非常麻烦,如table(X1), table(X2), ... ,table(Xn).有没有简单的语句一次性求解 ...

  3. GCC编译错误小结

    gcc编译时对’xxxx’未定义的引用问题可能错误 错误一: 没有实现xxxx 错误二: c++引用c语言so库,但是so库头文件没有extern "C" 错误三: 检查各个共享库 ...

  4. Linux系统查看系统是32位还是64位方法总结 in 创新实训

    这篇博客是总结.归纳查看Linux系统是32位还是64位的一些方法,很多内容来自网上网友的博客.本篇只是整理.梳理这方面的知识,方便自己忘记的时候随时查看. 方法1:getconf LONG_BIT ...

  5. HashMap HashTable ConcurrentHashMap

    1. Hashtable 和 HashMap (1)区别,这两个类主要有以下几方面的不同:Hashtable和HashMap都实现了Map接口,但是Hashtable的实现是基于Dictionary抽 ...

  6. 第三百七十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页

    第三百七十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页 逻辑处理函数 计算搜索耗时 在开始搜索前:start_time ...

  7. Java如何获取正在运行的线程的Id?

    在Java编程中,如何获取正在运行的线程的Id? 以下示例演示如何使用getThreadId()方法获取正在运行的线程的Id. package com.yiibai; public class IdT ...

  8. Spring JDBC查询数据

    以下示例将展示如何使用Spring jdbc进行查询数据记录,将从student表中查询记录. 语法: String selectQuery = "select * from student ...

  9. 使用Maven创建Web应用程序项目

    用到的技术/工具: Maven 3.3.3 Eclipse 4.3 JDK 8 Spring 4.1.1.RELEASED Tomcat 7 Logback 1.0.13 1. 从Maven模板创建W ...

  10. powerDesigner生成Html及Word

    转载地址:https://blog.csdn.net/zdp072/article/details/51900794 1:点击Reports 2:点击New Reports 3:定义名字,选择简体中文 ...