Dubbo学习笔记

Dubbo简介

Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各层之间解耦合(或者组大限度的松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供者(provider)和服务消费方(consumer)两个角色。关于注册中心、协议支持、服务监控等内容,详见后面描述。

Dubbo的总体架构,如图所示:

1.png

Dubbo框架设计一共划分了10层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝色背景的为服务消费方使用的接口,右边淡绿色的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口。

下面,结合Dubbo官方文档,我们分别理解一下框架分层架构中,各个层次的设计要点:

  1. 服务接口层(Service): 该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
  2. 配置层(Config): 对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类
  3. 服务代理层(Proxy): 服务接口透明代理,生成服务的客户端Stub和服务端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory
  4. 服务注册层(Registry): 封装服务地址的注册与发现,以服务URL为中心,扩展接口
  5. 集群层(Cluster): 封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
  6. 监控层(Monitor): RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService.
  7. 远程调用层(Protocol): 封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠拢,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
  8. 信息交换层(Exchange): 封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
  9. 网络传输层(Transport): 抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
  10. 数据序列化层(Serialize): 可复用的一些工具,扩展接口为Serialization、ObjectInput、ObjectOutput和ThreadPool。
    2.png

    Dubbo目录支持的协议:
  • Dubbo协议
  • Hessian协议
  • HTTP协议
  • WebService协议
  • Thrift协议
  • Memcached协议
  • Redis协议

SPI机制

在Dubbo中,SPI是一个非常核心的机制,贯穿在几乎所有的流程中。搞懂这块内容,是接下来了解Dubbo更多源码的关键因素。

Dubbo是基于Java原生SPI机制思想的一个改进,所以,先从Java SPI机制开始了解,然后再去学习Dubbo的SPI,就比较容易了。

关于Java的SPI机制

SPI全称(service provider interface),是JDK内置的一种服务提供发现机制,目前市面上有很多框架都是用它来做服务的扩展发现,大家耳熟能详的如JDBC、日志框架都有用到;

简单来说,它是一种动态替换发现的机制。举个简单的例子,如果我们定义了一个规范,需要第三方厂商去实现,那么对于我们应用方来说,只需要集成对应厂商的插件,即可以完成对应规范的实现机制。形成一种插拔式的扩展手段。

实现一个SPI机制的流程图如下:


3.png

SPI规范总结

实现SPI,就需要按照SPI本身定义的规范来进行配置,SPI规范如下:

  1. 需要再classpath下创建一个目录,该目录命名必须是:META-INF/services

  2. 在该目录下创建一个properties文件,该文件需要满足以下几个条件

    1. 文件名必须是扩展的接口的全路径名称
    2. 文件内部描述的是该扩展接口的所有实现类
    3. 文件的编码格式是UTF-8
  3. 通过java.util.ServiceLoader的加载机制来实现

SPI的实际应用

SPI在很多地方有应用,大家可以看看最常用的java.sql.Driver驱动。JDK官方提供了java.sql.Driver这个驱动扩展点,但是你们并没有看到JDK中有对应的Driver实现。那在哪里实现呢?

以连接Mysql为例,我们需要添加mysql-connector-java依赖。然后,你们可以在这个jar包中找到SPI的配置信息。如下图,所以java.sql.Driver由各个数据库厂商自行实现。这就是SPI的实际应用。当然除了这个意外,大家在spring的保重也可以看到相应的痕迹

4.jpeg

SPI的缺点

  1. JDK标准的SPI会一次性加载实例化扩展点的所有实现,什么意思呢?就是如果你在META-INF/services下的文件里面加了N个实现类,那么JDK启动的时候都会一次性全部加载。那么如果有的扩展点实现初始化很耗时或者如果有些实现类并没有用到,那么会浪费资源
  2. 如果扩展点加载失败,会导致调用方报错,而且这个错误很难定位到原因

Dubbo优化后的SPI实现

基于Dubbo提供的SPI规范实现自己的扩展

Dubbo的SPI机制规范

大部分的思想都是和SPI是一样,只是下面两个地方有差异。

  1. 需要再resource目录下配置META-INF/dubbo或者META-INF/dubbo/internal或者META-INF/services,并基于SPI接口去创建一个文件
  2. 文件名称和接口名称保持一致,文件内容和SPI有差异,内容是KEY=VALUE

配置优先级

以timeout为例,显示了配置的查找顺序,其它retries,loadbalance等类似

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

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

建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方通知引用多个服务,就不需要关系每个服务的超时设置

容错策略

我们使用Dubbo做分布式服务需要了解Dubbo服务容错策略,Dubbo官网总共提出总共有六种容错策略,下面将详细介绍这六种容错策略区别。

5.png
  1. Failover Cluster模式(缺省)
    • 失败自动切换,当出现失败,重试其它服务器。
    • 通常用于读操作,但重试会带来更长延迟。
    • 可通过retries="2"来设置重试次数(不含第一次)。
  2. Failfast Cluster
    • 快速失败,只发起一次调用,失败立即报错。
    • 通常用于非幂等性的写操作,比如新增记录。
  3. Failsafe Cluster
    • 失败安全,出现异常时,直接忽略。
    • 通常用于写入审计日志等操作。
  4. Failback Cluster
    • 失败自动恢复,后台记录失败请求,定时重发。
    • 通常用于消息通知操作。
  5. Forking Cluster
    • 并行调用多个服务器,只要一个成功即返回。
    • 通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过forks="2"来设置最大并行数。
  6. Broadcast Cluster
    • 广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)
    • 通常用于通知所有提供者更新缓存或日志等本地资源信息。

Dubbo容错策略成熟粒度:

6.png

总结:在实际引用中,查询语句容错策略建议使用默认Failover Cluster,而增删改建议使用Failfast Cluster或者使用Failover Cluster(retries=0)策略,防止出现数据重复添加等等其它问题。建议在设计接口时候把查询接口方法单独做一个接口来提供查询。

服务降级

降级的目的是为了保证核心服务可用。

降级可用有几个层面的分类:自动降级和人工降级;按照功能可用分为:读服务降级和写服务降级。

  • 对一些非核心服务进行人工降级,在大促之前通过降级开关关闭哪些推荐内容、评价等对主流程没有影响的功能
  • 故障降级,比如调用的远程服务挂了,网络故障、或者RPC服务返回异常。那么可以直接降级,降级的方案比如设置默认值、采用兜底数据(系统推荐的行为广告挂了,可以提前准备静态页面做返回)等等
  • 限流降级,在秒杀这种流量比较集中并且流量特别大的情况下,因为突发访问量特别大可能会导致系统支撑不了。这个时候可以采用限流来限制访问量。当达到阀值时,后续的请求被降级,比如进入排队页面,比如跳转到错误页(活动太火爆,稍后重试等)

dubbo的降级方式:Mock

实现步骤:

  • 在client端创建一个TestMock类,实现对应ITest的接口(需要对哪个接口进行mock,就实现哪个),名称必须以Mock结尾
  • 在client端的xml配置文件中,添加如下配置,增加一个mock属性指向创建的TestMock
  • 模拟错误(设置timeout),模拟超时异常,运行测试代码即可访问到TestMock这个类。当服务端故障解除以后,调用过程将恢复正常
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352