dubbo

dubbo的基本需求

  • 动态的注册和发现服务,实现软负载,降低对F5硬件负载的依赖。
  • 理清服务间的依赖关系。
  • 统计每个服务的调用量、相应时间。可以动态调整每个机器的权重。

dubbo的架构

image
节点 | 角色说明
—|—
provider | 暴露服务的服务提供方
consumer | 调用远程服务的服务消费方
registry | 服务注册于发现的注册中心
Monitor | 统计服务的调用次数和调用时间的监控中心
Container| 服务运行容器

调用关系说明

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,在选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

dubbo架构具有以下几个特点:分别是连通性、健壮性、伸缩性以及未来架构的升级性。

连通性

  • 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。
  • 监控中心负责统计各个服务的调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示。
  • 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销。
  • 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法之间调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销。
  • 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外。
  • 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者。
  • 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表。
  • 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者。

健壮性

  • 监控中心宕掉不影响使用,只是丢失部分采样数据。
  • 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务。
  • 注册中心对等集群,任意一台宕掉后,将自动切换到另一台。
  • 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯。
  • 服务提供者无状态,任意一台宕掉后,不影响使用。
  • 服务提供者全部宕掉后,服务消费者应有将无法使用,并无限次重连等待服务提供者恢复。

伸缩性

  • 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心。
  • 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者。

升级性

  当服务集群规模进一步扩大,带动IT治理结构进一步升级,需要实现动态部署,进行流动计算,现有分布式服务架构不会带来阻力。下图是未来可能的一种架构:

image

节点 说明
Deployer 自动部署服务的本地代理
Repository 仓库用于存储服务应用发布包
Scheduler 调度中心基于服务压力自动增减服务提供者
Admin 统一管理控制台
Registry 服务注册与发现的注册中心
Monitor 统计服务的调用次数和调用压力的监控中心

基于spring的配置

1.本地配置很简单,和使用本地的service类,没有区别。

1
2
3
4
<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” />
<bean id=“xxxAction” class=“com.xxx.XxxAction”>
<property name=“xxxService” ref=“xxxService” />
</bean>

2.远程配置需要将本地的配置拆分成两份,将服务定义部分放在服务提供方remote-provider.xml,将服务引用部分放在服务消费方remote-consumer.xml;并在提供方增加暴露服务配置,在消费方增加引用服务配置

remote-provider.xml:

1
2
3
4
<!-- 和本地服务一样实现远程服务;加上url="ip:port",相当于直连,不经过注册中心,一般本地调试的时候,会设置成localhost -->
<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” />
<!-- 增加暴露远程服务配置 -->
<dubbo:service interface=“com.xxx.XxxService” ref=“xxxService” />

remote-consumer.xml:

1
2
3
4
5
6
<!-- 增加引用远程服务配置 -->
<dubbo:reference id=“xxxService” interface=“com.xxx.XxxService” />
<!-- 和本地服务一样使用远程服务 -->
<bean id=“xxxAction” class=“com.xxx.XxxAction”>
<property name=“xxxService” ref=“xxxService” />
</bean>

配置方式

xml配置

标签 用途 解释
服务配置 用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心
引用配置 用于创建一个远程服务代理,一个引用可以指向多个注册中心
协议配置 用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受
应用配置 用于配置当前的应用信息,不管该应用是提供者还是消费者
模块配置 用于配置当前模块信息,可选
注册中心配置 用于配置连接注册中心相关信息
监控中心配置 用于配置连接监控中心相关信息,可选
提供方配置 当ProtocolConfig和ServerConfig某属性没有配置时,采用此缺省值,可选
消费方配置 当ReferenceConfig某属性没有配置时,采用此缺省值,可选
方法配置 用于ServiceConfig和ReferenceConfig指定方法级的配置信息
参数配置 用于指定方法参数配置

配置覆盖关系

  • 方法级优先,接口级次之,全局配置再次之。
  • 如果级别一样,则消费方优先,提供方次之。

  服务提供方的配置,通过URL经过注册中心传递给消费方。

  下图以timeout参数为例,展示了参数配置的传递过程:

image

属性配置

  如果公共配置很简单,没有多注册中心,多协议等情况,或者想多个 Spring 容器想共享配置,可以使用 dubbo.properties 作为缺省配置。

  Dubbo 将自动加载 classpath 根目录下的 dubbo.properties,可以通过JVM启动参数 -Ddubbo.properties.file=xxx.properties 改变缺省配置位置。

API配置

注解配置

==实际开发中,使用xml配置居多,至少我们公司是这样。==

dubbo负载均衡策略

Random LoadBalance

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

RoundRobin LoadBalance

  • 轮循,按公约后的权重设置轮循比率。
  • 存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那里,久而久之,所有请求都卡在调第二台上。

LeastActive LoadBalance

  • 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
  • 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

ConsistentHash LoadBalance

  • 一致性hash,相同参数的请求总是发送到同一提供者。
  • 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其他提供者,不会引起剧烈变动。