Dubbo 开发随笔

Dubbo 基础使用

Dubbot 支持的通信协议

官方文档说明

协议名称协议描述
Dubbo 协议 Dubbo 默认使用的协议,基于单一长连接和 NIO 异步通讯
Hessian2 协议轻量级远程调用协议,基于 HTTP 传输
Thrift 协议跨平台、跨语言的服务接口定义和序列化协议,基于 TCP 传输
gRPC 协议 Google 开发的高性能、开源、通用的 RPC 框架,基于 TCP 传输
RMI 协议基于 Java RMI(远程方法调用)协议,通过 Java 对象序列化进行数据传输
HTTP 协议基于 HTTP 协议进行通信
REST 协议基于 RESTful 风格的协议,可以使用 HTTP 或 Websocket 进行通信
Webservice 协议协议 基于 SOAP 规范的 Webservice 协议,通过 XML 格式进行数据传输
Memcached 协议基于 Memcached 协议实现缓存同步
Redis 协议基于 Redis 协议实现数据存储和同步

Dubbo 整合框架

Spring 与 SpringBoot 整合

  • 整合 Dubbo 的三种方式

    • 三种方式分别为:XML 配置、Annotation 配置、API 配置
    • Spring 与 SpringBoot 都支持以 XML 配置、Annotation 配置整合 Dubbo
    • 由于使用基于注解的方式整合 Dubbo,无法实现 Dubbo 方法级的配置(即 dubbo:method 标签的功能),如果 Spring、SpringBoot 需要用到 Dubbo 方法级的配置,那么则需要使用 XML 的方式整合 Dubbo
  • Spring 与 SpringBoot 整合 Dubbo 简单总结

    • SpringBoot + XML: @ImportResource
    • SpringBoot + Annotation: @EnableDubbo
    • Spring + Annotation: AnnotationConfigApplicationContext
    • Spring + XML: ClassPathXmlApplicationContextFileSystemXmlApplicationContext

Dubbo 服务高可用

Dubbo 服务降级

当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。Dubbo 可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。Dubbo 向注册中心写入动态配置覆盖规则如下:

1
2
3
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));

其中:

  • mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
  • 还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
  • 利用 Dubbo-Admin 的 UI 界面(旧版),可以方便地对服务进行屏蔽 / 恢复(mock=force:return+null)、容错 / 恢复(mock=fail:return+null)处理,即上面提到的两种服务降级方式

Dubbo 集群容错

在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。真正的生产环境中,一般使用 Hystrix 进行容错处理。

  • Failover Cluster:失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries=”2” 来设置重试次数 (不含第一次)。
  • Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
  • Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
  • Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
  • Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=”2” 来设置最大并行数。
  • Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。
1
2
3
4
<!-- Failover 重试次数的几种配置方式如下 -->
<dubbo:service retries="2" />
<dubbo:reference retries="2" />
<dubbo:reference> <dubbo:method name="findFoo" retries="2" /> </dubbo:reference>
1
2
3
<!-- 集群模式配置,按照以下几种配置方式在服务提供方和消费方配置集群模式 -->
<dubbo:service cluster="failsafe" />
<dubbo:reference cluster="failsafe" />

宕机环境下的健壮性与高可用性

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

Dubbo 源码剖析

Dubbo 的服务暴露

dubbo-export

Dubbo 的服务引用

dubbo-reference

Dubbo 配置类之间的关系

dubbo-config

常见使用错误

SpringBoot 整合 Dubbo 出错

错误信息:

1
SpringBoot-2.1.0+ 整合 Apache Dubbo-2.7.0,启动应用后提示需要添加SpringBoot配置 “spring.main.allow-bean-definition-overriding=true”

异常日志:

1
2
3
4
5
6
7
8
9
10
11
***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'dubboConfigConfiguration.Single', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

异常分析:

1
2
3
问题是由注解 @EnableDubbo、@EnableDubboConfig 的使用所导致,具体可参考以下资料:
https://github.com/apache/dubbo/issues/3193
https://github.com/apache/dubbo-spring-boot-project/issues/476

解决方法:

1
2
3
4
5
方法一:
往 SpringBoot 的配置文件(application.properties)中添加对应配置,允许在 Spring 容器内可以覆盖 Bean 的定义: spring.main.allow-bean-definition-overriding=true

方法二:
将 Apache Dubbo-2.7.0 升级到 Apache Dubbo-2.7.1 版本,具体可参考:https://github.com/apache/dubbo-spring-boot-project/issues/467