dubbo实现原理学习总结

1、什么是dubbo?
    Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。
    Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

2、框架分层架构中,各个层次的设计要点:

dubbo实现原理学习总结

    服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
    配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
    服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
    服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。
    集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
    监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
    远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
    信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
    网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心
    扩展接口为Channel、Transporter、Client、Server和Codec。
    数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。
    
3、Dubbo以包结构来组织各个模块:
    dubbo-common 公共逻辑模块,包括Util类和通用模型。
    dubbo-remoting 远程通讯模块,相当于Dubbo协议的实现,如果RPC用RMI协议则不需要使用此包。
    dubbo-rpc 远程调用模块,抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理。
    dubbo-cluster 集群模块,将多个服务提供方伪装为一个提供方,包括:负载均衡、容错、路由等,集群的地址列表可以是静态配置的,也可以是由注册中心下发。
    dubbo-registry 注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。
    dubbo-monitor 监控模块,统计服务调用次数,调用时间的,调用链跟踪的服务。
    dubbo-config 配置模块,是Dubbo对外的API,用户通过Config使用Dubbo,隐藏Dubbo所有细节。
    dubbo-container 容器模块,是一个Standalone的容器,以简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务。

4、服务接口的流程
    a、服务方定义接口
    b、服务方实现接口
    c、服务方用spring配置暴露接口(provider.xml中配置bean)
        在 Provider 端配置的 Provider 端属性有:

        threads:服务线程池大小
        executes:一个服务提供者并行执行请求上限,即当 Provider 对一个服务的并发调用达到上限后,新调用会阻塞,此时 Consumer 可能会超时。在方法上配置 dubbo:method 则针对该方法进行并发限制,在接口上配置 dubbo:service,则针对该服务进行并发限制
    d、服务方的项目启动时是要加载provider.xml配置
    e、消费者通过 Spring 配置引用远程服务(consumer.xml引入bean配置)
        在 Provider 端配置的 Consumer 端属性有:

        timeout:方法调用的超时时间
        retries:失败重试次数,缺省是 2 [2]
        loadbalance:负载均衡算法 [3],缺省是随机 random。还可以配置轮询 roundrobin、最不活跃优先 [4] leastactive 和一致性哈希 consistenthash 等
        actives:消费者端的最大并发调用限制,即当 Consumer 对一个服务的并发调用到上限后,新调用会阻塞直到超时,在方法上配置 dubbo:method 则针对该方法进行并发限制,在接口上配置 dubbo:service,则针对该服务进行并发限制
    f、消费方加载Spring配置,并调用远程服务
    
5、Dubbo支持的协议:
    Dubbo协议 Hessian协议
    HTTP协议 RMI协议
    WebService协议
    Thrift协议 Memcached协议 Redis协议
    在通信过程中,不同的服务等级一般对应着不同的服务质量,那么选择合适的协议便是一件非常重要的事情。你可以根据你应用的创建来选择。例如,使用RMI协议,一般会受到防火墙的限制,所以对于外部与内部进行通信的场景,就不要使用RMI协议,而是基于HTTP协议或者Hessian协议。

    注意:dubbo默认协议是dubbo协议
        连接个数:单连接
        连接方式:长连接
        传输协议:TCP
        传输方式:NIO异步传输
        序列化:Hessian二进制序列化
        适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要使用dubbo协议传输大文件或超大字符串
        使用场景:常规远程服务方法调用
6、Dubbo服务运行的三种方式如下:
    1、使用Servlet容器运行(Tomcat、Jetty等) -不可用 
      缺点:增加复杂性(端口、管理) 
      浪费资源(内存) 
      需要占用多个端口和内存,这种方式是不可取的

    2、自己建立Main方法类运行(Srping容器)
      缺点:Dobbo本省提供的高级特性没用上,自己的启动类可能有缺陷

    3、使用Dubbo框架提供的Main方法类来运行(Spring 容器) 建议使用 
      优点:框架本身提供(com.alibaba.dubbo.container.Main),可是现优雅关机(ShutdownHook)。
      这个不存在缓存,生产者开启或者关闭之后dubbo-admin可以马上感知到。

7、 集群容错模式:

  Failover Cluster

    失败自动切换,当出现失败,重试其它服务器。(缺省)

    通常用于读操作,但重试会带来更长延迟。

    可通过retries="2"来设置重试次数(不含第一次)。

  Failfast Cluster

    快速失败,只发起一次调用,失败立即报错。

    通常用于非幂等性的写操作,比如新增记录。

  Failsafe Cluster

    失败安全,出现异常时,直接忽略。

    通常用于写入审计日志等操作。

  Failback Cluster

    失败自动恢复,后台记录失败请求,定时重发。

    通常用于消息通知操作。

  Forking Cluster

    并行调用多个服务器,只要一个成功即返回。

    通常用于实时性要求较高的读操作,但需要浪费更多服务资源。

    可通过forks="2"来设置最大并行数。

  Broadcast Cluster

    广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)

    通常用于通知所有提供者更新缓存或日志等本地资源信息。
    
8、dubbo负载均衡策略:

        在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。

    RandomLoadBalance

        随机,按权重设置随机概率。

        在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

    RoundRobin LoadBalance

        轮循,按公约后的权重设置轮循比率。

        存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

    LeastActive LoadBalance

        最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

        使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

   ConsistentHashLoadBalance

        一致性Hash,相同参数的请求总是发到同一提供者。

        当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
            
    

--------------------------------生如蝼蚁,却有鸿鹄之志;命如纸薄,但有不屈之心;乾坤未定,你我皆是黑马;祝你我早日飞黄腾达!