Dubbo整体概念整理

整理自官网,对整体理解Dubbo很有作用.

作用

Apache Dubbo 是一款高性能,轻量级的Java RPC框架.

三大核心能力

面向接口的远程方法调用

智能容错和负载均衡

以及服务自动注册和发现

健壮性

监控中心宕掉不影响使用,只是丢失部分采样数据.

数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务.

注册中心对等集群,任意一台宕掉后,将自动切换到另一台.

注册中心全部宕掉后,服务提供者 和 服务消费者 仍能通过本地缓存通讯.

服务提供者无状态,任意一台宕掉后,不影响使用.

服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复.

伸缩性

注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心.

服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者.

协议

  • Dubbo协议
    采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用)
    在大文件传输时,单一连接会成为瓶颈
    可用于生产环境

  • Rmi协议
    可与原生RMI互操作,基于TCP协议
    偶尔会连接失败,需重建Stub 可用于生产环境

  • Hessian协议
    可与原生Hessian互操作,基于HTTP协议
    需hessian.jar支持,http短连接的开销大 可用于生产环境

nio框架

  • Netty Transporter
    JBoss 的 NIO 框架,性能较好(推荐使用)
    一次请求派发两种事件,需屏蔽无用事件.

  • Mina Transporter
    老牌NIO框架,稳定
    待发送消息队列派发不及时,大压力下,会出现FullGC.

序列化

  • Hessian Serialization
    Stable 性能较好,多语言支持(推荐使用)
    Hessian的各版本兼容性不好,可能和应用使用的Hessian冲突,Dubbo内嵌了hessian3.2.1的源码
    可用于生产环境

  • Dubbo Serialization
    Tested
    通过不传送POJO的类元信息,在大量POJO传输时,性能较好
    当参数对象增加字段时,需外部文件声明 试用

  • Json Serialization
    纯文本,可跨语言解析,缺省采用FastJson解析
    性能较差 试用

  • Java Serialization
    Java原生支持 性能较差
    可用于生产环境

生成代理类

  • Javassist ProxyFactory
    通过字节码生成代替反射,性能比较好(推荐使用)
    依赖于javassist.jar包,占用JVM的Perm内存,Perm可能要设大一些:java -XX:PermSize=128m
    可用于生产环境

  • Jdk ProxyFactory
    JDK原生支持 性能较差 可用于生产环境

容错机制

  • Failover Cluster
    失败自动切换,当出现失败,重试其它服务器,通常用于读操作(推荐使用)
    重试会带来更长延迟

  • Failfast Cluster
    快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作 如果有机器正在重启,可能会出现调用失败 可用于生产环境

  • Failsafe Cluster
    失败安全,出现异常时,直接忽略,通常用于写入审计日志等操作
    调用信息丢失
    可用于生产环境 Monitor

  • Failback Cluster
    失败自动恢复,后台记录失败请求,定时重发,通常用于消息通知操作
    不可靠,重启丢失
    可用于生产环境 Registry

  • Forking Cluster
    并行调用多个服务器,只要一个成功即返回,通常用于实时性要求较高的读操作
    需要浪费更多服务资源
    可用于生产环境

  • Broadcast Cluster
    广播调用所有提供者,逐个调用,任意一台报错则报错,通常用于更新提供方本地状态
    速度慢,任意一台报错则报错
    可用于生产环境

负载均衡算法

  • Random LoadBalance
    随机,按权重设置随机概率(推荐使用)
    在一个截面上碰撞的概率高,重试时,可能出现瞬间压力不均

  • RoundRobin LoadBalance
    轮询,按公约后的权重设置轮询比率
    存在慢的机器累积请求问题,极端情况可能产生雪崩

  • LeastActive LoadBalance
    最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差,使慢的机器收到更少请求
    不支持权重,在容量规划时,不能通过权重把压力导向一台机器压测容量

  • ConsistentHash LoadBalance
    一致性Hash,相同参数的请求总是发到同一提供者,当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动
    压力分摊不均

线程模型

线程模型

IO线程自行处理:
如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,比如只是在内存中记个标识,则直接在 IO 线程上处理更快,因为减少了线程池调度.

派发到线程池处理:
但如果事件处理逻辑较慢,或者需要发起新的 IO 请求,比如需要查询数据库,则必须派发到线程池,否则 IO 线程阻塞,将导致不能接收其它请求.

如果用 IO 线程处理事件,又在事件处理过程中发起新的 IO 请求,比如在连接事件中发起登录请求,会报"可能引发死锁"异常,但不会真死锁.

分层

业务层: Service

RPC层: Config, Proxy, Registry, Cluster, Monitor, Protocol

Remote层: Exchange, Transport, Serialize

  • Service:
    业务层.包括业务代码的接口与实现.

  • config 配置层:
    对外配置接口,以 ServiceConfig(暴露的服务配置), ReferenceConfig(引用的服务配置) 为中心,可以直接初始化配置类,也可以通过 spring 解析配置生成配置类.该层管理整个dubbo的配置.

  • proxy 服务代理层:
    服务代理层.在Dubbo中,无论 服务提供者 还是 服务消费者,框架都会生成一个代理类,整个过程对上层透明.
    当调用一个远程接口时,看起来就像调用一个本地接口一样.
    代理层会自动做远程调用并返回结果,即让业务层对远程调用完全无感知.
    服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton, 以 ServiceProxy 为中心,扩展接口为 ProxyFactory

  • registry 注册中心层:
    负责 Dubbo 框架的服务注册与发现.当有新的服务加入或旧服务下线时,注册中心都会感知并通知给所有订阅方.以服务 URL 为中心,扩展接口为 RegistryFactory, Registry, RegistryService

  • cluster 路由层:
    封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 Cluster, Directory, Router, LoadBalance.
    该层主要负责:
    远程调用失败时的容错策略(如失败重试,快速失败);
    选择具体调用节点时的负载均衡策略(如随机,一致性Hash等);
    特殊调用路径的路由策略(如某个消费者只会调用某个IP的生产者)

  • monitor 监控层:
    RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory, Monitor, MonitorService

  • protocol 远程调用层:
    封装 RPC 调用具体过程.,以 Invocation, Result 为中心,扩展接口为 Protocol, Invoker, Exporter.
    是服务域,它是 Invoker 暴露和引用的主功能入口,它负责 Invoker 的生命周期管理.
    Protocol 是核心层,也就是只要有 Protocol + Invoker + Exporter 就可以完成非透明的 RPC 调用,然后在 Invoker 的主过程上 Filter 拦截点.
    Invoker 是 Dubbo 的核心模型,框架中所有其他模型都向它靠拢,或者转换成它,它代表一个 可执行体.
    允许向它发起 invoke 调用,它可能是执行一个本地的接口实现,也可能是一个远程的实现,还可能是一个集群实现.

  • exchange 信息交换层:
    建立 Request-Response 模型,封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer

  • transport 网络传输层:
    抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel, Transporter, Client, Server, Codec

  • serialize 数据序列化层:
    若数据要通过网络进行发送,则需要先做序列化,变成二进制流.
    序列化层负责管理整个框架网络传输时的 序列化/反序列化 工作.
    可复用的一些工具,扩展接口为 Serialization, ObjectInput, ObjectOutput, ThreadPool

分层关系说明

在 RPC 中,Protocol 是核心层,也就是只要有 Protocol + Invoker + Exporter 就可以完成非透明的 RPC 调用,然后在 Invoker 的主过程上 Filter 拦截点.

Consumer 和 Provider 是抽象概念,只是想让看图者更直观的了解哪些类分属于客户端与服务器端,不用 Client 和 Server 的原因是 Dubbo 在很多场景下都使用 Provider, Consumer, Registry, Monitor 划分逻辑拓普节点,保持统一概念.

而 Cluster 是外围概念,所以 Cluster 的目的是将多个 Invoker 伪装成一个 Invoker,这样其它人只要关注 Protocol 层 Invoker 即可,加上 Cluster 或者去掉 Cluster 对其它层都不会造成影响,因为只有一个提
供者时,是不需要 Cluster 的.

Proxy 层封装了所有接口的透明化代理,而在其它层都以 Invoker 为中心,只有到了暴露给用户使用时,才用 Proxy 将 Invoker 转成接口,或将接口实现转成 Invoker,也就是去掉 Proxy 层 RPC 是可以 Run 的,只是不那么透明,不那么看起来像调本地服务一样调远程服务.

而 Remoting 实现是 Dubbo 协议的实现,如果你选择 RMI 协议,整个 Remoting 都不会用上,Remoting 内部再划为 Transport 传输层和 Exchange 信息交换层,Transport 层只负责单向消息传输,是对 Mina, Netty, Grizzly 的抽象,它也可以扩展 UDP 传输,而 Exchange 层是在传输层之上封装了 Request-Response 语义.

Registry 和 Monitor 实际上不算一层,而是一个独立的节点,只是为了全局概览,用层的方式画在一起.

  • dubbo-common
    公共逻辑模块:包括 Util 类和通用模型.
    serialize 层放在 common 模块中,以便更大程度复用.

  • dubbo-remoting
    远程通讯模块:相当于 Dubbo 协议的实现,如果 RPC 用 RMI协议则不需要使用此包.
    transport 层和 exchange 层都放在 remoting 模块中,为 rpc 调用的通讯基础.
    Remoting 实现是 Dubbo 协议的实现,如果你选择 RMI 协议,整个 Remoting 都不会用上,Remoting 内部再划为 Transport 传输层和 Exchange 信息交换层,
    Transport 层只负责单向消息传输,是对 Mina, Netty, Grizzly 的抽象,它也可以扩展 UDP 传输,而 Exchange 层是在传输层之上封装了 Request-Response 语义.

  • dubbo-rpc
    远程调用模块:抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理.
    protocol 层和 proxy 层都放在 rpc 模块中,这两层是 rpc 的核心,在不需要集群也就是只有一个提供者时,可以只使用这两层完成 rpc 调用.

  • dubbo-cluster
    集群模块:将多个服务提供方伪装为一个提供方,包括:负载均衡, 容错,路由等,集群的地址列表可以是静态配置的,也可以是由注册中心下发.

  • dubbo-registry
    注册中心模块:基于注册中心下发地址的集群方式,以及对各种注册中心的抽象.

  • dubbo-monitor
    监控模块:统计服务调用次数,调用时间的,调用链跟踪的服务.

  • dubbo-config
    配置模块:是 Dubbo 对外的 API,用户通过 Config 使用Dubbo,隐藏 Dubbo 所有细节.

  • dubbo-container
    容器模块:是一个 Standlone 的容器,以简单的 Main 加载 Spring 启动,因为服务通常不需要 Tomcat/JBoss 等 Web 容器的特性,没必要用 Web 容器去加载服务.
    整体上按照分层结构进行分包,与分层的不同点在于:
    container 为服务容器,用于部署运行服务,没有在层中画出.
    protocol 层和 proxy 层都放在 rpc 模块中,这两层是 rpc 的核心,在不需要集群也就是只有一个提供者时,可以只使用这两层完成 rpc 调用.
    transport 层和 exchange 层都放在 remoting 模块中,为 rpc 调用的通讯基础.
    serialize 层放在 common 模块中,以便更大程度复用.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlyingZCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值