Nivelle 开拓视野冲破艰险看见世界 身临其境贴近彼此感受生活

dubbo

2018-08-24

dubbo

定义

Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,Dubbo就是个服务框架,说白了就是个远程服务调用的分布式框架。

核心方法实现

1. 服务暴露

(1)设置了延迟暴露,dubbo在Spring实例化bean(initializeBean)的时候会对实现了InitializingBean的类进行回调,回调方法是afterPropertySet(),如果设置了延迟暴露,dubbo在这个方法中进行服务的发布。

(2)没有设置延迟或者延迟为-1,dubbo会在Spring实例化完bean之后,在刷新容器最后一步发布ContextRefreshEvent事件的时候,通知实现了ApplicationListener的类进行回调onApplicationEvent,dubbo会在这个方法中发布服务

不管延迟与否,都是使用ServiceConfig的export()方法进行服务的暴露。使用export初始化的时候会将Bean对象转换成URL格式,所有Bean属性转换成URL的参数。

2. 服务获取

流程详解

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

调用开始是在ReferenceConfig.get()

注册中心中服务的结构:

image

集群容错

概念:

容错方案 | 描述 —|— FailOver | 失败自动切换,自动重试其他服务,适合读操作 FailFast | 快速失败,立即报错,适合写操作 FailSafe | 失败安全,直接忽略,适合类似写日志 FailBack | 失败自动恢复,记录失败请求,定时重发,适合消息重试 Forking | 并行调用多个服务器,只要一个成功就立即返回,适合对读性能要求很高的服务 BroadCast | 广播逐个调用所有提供者,任意一个报错则报错。

面对服务消费方,业务逻辑调用一个服务的时候,真正调用的是一个proxy , 该proxy会把调用转化成调用指定的invoker(Cluser将Directory中的多个Invoker伪装成一个Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个(LoadBalance),Invoker封装了Provider地址和Service接口信息)。这一系列的委托调用过程就完成了服务治理。

image

代码原理
  • 集群容错: ``` @SPI(FailoverCluster.NAME) public interface Cluster {

    /**

    • Merge the directory invokers to a virtual invoker.
    • @param
    • @param directory
    • @return cluster invoker
    • @throws RpcException */ @Adaptive
    Invoker join(Directory directory) throws RpcException;

}

- LoadBalance

@SPI(RandomLoadBalance.NAME) public interface LoadBalance {

/**
 * select one invoker in list.
 * 
 * @param invokers invokers.
 * @param url refer url
 * @param invocation invocation.
 * @return selected invoker.
 */
@Adaptive("loadbalance")
<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;

} ```

Cluster内置了9个实现类,实现不同的容错算法。其中结合了负载均衡方法

负载均衡

负载均衡策略 说明
Random 随机,可以按照权重
RoundRobin 轮询,按照公约后的权重设置轮询比率
LeastActive 最少活跃调用数,相同活跃数的随机
ConsistentHash 一致性Hash,相同参数的请求总是发送到同一个提供者

dubbo启动时依赖的服务不可用

序列化框架

推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。

常见配置

provider
  • 当一个接口有多种实现时,可以用 group 属性来分组,服务提供方和消费方都指定同一个 group 即可。
  • 可以用版本号(version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。
  • timeout:远程调用超时时间,如果客户端和服务端都配置了,以客户端为主,客户端没有配置以服务端为准
  • retries:远程调用重试次数,不包括第一次调用,默认2
  • filter:服务提供方远程过程拦截器名称,多个名称用逗号分割,Spring拦截器可以拦截web接口,无法拦截dubbo接口

consumer
  • url :点对点直连服务提供者地址,将绕过注册中心
  • cache :以调用参数为key,缓存返回结果,可选lru,threadLocal,
  • Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,默认 check=”true”,可以通过 check=”false” 关闭检查。

注册中心配置
  • file :使用文件缓存注册中心地址列表以及服务提供者列表,应用重启时将基于此文件恢复。注意:两个注册中心不能使用同一文件存储。

在provider上可以配置的consumer属性

  • timeout :方法调用超时
  • retries:失败重试次数
  • loadbalance :负载均衡算法,默认随机
  • actives 消费者端,最大并发调用限制

dubbo服务之间的调用是阻塞的么

默认是同步等待结果阻塞的,支持异步调用。

Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。


下一篇 hashMap原理

评论