zoukankan      html  css  js  c++  java
  • Dubbo原码解析(version:2.5.3)

    一、启动
    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
    View Code

    容器里面相关的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.jarMETA-INFdubbointernalcom.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.jarMETA-INFdubbointernalcom.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
  • 相关阅读:
    ♫【插件】插入Flash swfobject
    ☀【Alice】
    _#【Vim】
    _#【选择器】链式class选择器
    _#【HTML】
    _#【CSS】display:inlineblock
    【折叠】一
    图解SSIS自动维护SQL索引
    wininet.dll函数库:检查网络状态
    sqlserver中动态sql语句应用
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/6635199.html
Copyright © 2011-2022 走看看