Dubbo 2 入门教程之二

大纲

前言

学习资源

Dubbo 核心特性

代码下载

本节完整的案例代码可以直接从 GitHub 下载对应章节 dubbo-lesson-06

地址缓存

特性说明

当注册中心宕机后,Dubbo 服务消费者是否可以正常调用服务提供者的接口?

  • 直连模式(Direct Connection):

    • 如果服务消费者配置了直连模式(即直接指定了服务提供者的地址,而不依赖注册中心),那么即使注册中心宕机,服务消费者仍然可以正常调用服务提供者的接口。
  • 注册中心模式(Registry Mode):

    • Dubbo 的服务消费者在启动时会从注册中心拉取服务提供者的地址列表,并将其缓存在本地,以后再调用服务时就不需要访问注册中心。当服务提供者的地址发生变化后,注册中心会通知服务消费者更新服务提供者的地址。
    • 如果注册中心宕机,但服务消费者在注册中心宕机之前已经成功启动并获得了服务提供者的地址列表,那么服务消费者可以直接使用本地缓存的地址列表继续调用服务提供者的接口。
    • 如果注册中心宕机,且服务消费者在注册中心宕机后才启动,由于无法从注册中心获取服务提供者的地址列表,因此服务消费者将无法正常调用服务提供者的接口。

Dubbo 的集群容错策略

  • Dubbo 提供了多种集群容错策略,如果在消费者的配置中启用了这些机制,并且本地有多个服务提供者的地址,那么即使某些提供者不可用,服务调用可能仍然成功。

超时时间

特性说明

特别注意

  • Dubbo 的调用超时时间(默认是 1000,单位是毫秒),支持在服务消费者和服务提供者两边进行配置。
  • 如果服务消费者和服务提供者都配置了超时时间,那么服务消费者的配置优先级更高。
  • 由于服务提供者最了解接口的业务逻辑,因此在企业开发中,建议在服务提供者中配置超时时间。

使用方式

注解配置方式

接口级别配置超时时间

  • 服务提供者配置超时时间(推荐)
1
2
3
4
5
6
7
8
9
10
11
12
/**
* 暴露 Dubbo 服务
*/
@DubboService(timeout = 1000)
public class UserServiceImpl implements UserService {

@Override
public User getById(Long id) {
return new User(id, "Peter", 18);
}

}
  • 服务消费者配置超时时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
@RequestMapping("/user")
public class UserController {

/**
* 引用 Dubbo 服务
*/
@DubboReference(timeout = 1000)
private UserService userService;

@GetMapping("/getById/{id}")
public User getById(@PathVariable("id") Long id) {
return userService.getById(id);
}

}

方法级别配置超时时间

  • 服务提供者配置超时时间(推荐)
1
2
3
4
5
6
7
8
9
10
11
12
/**
* 暴露 Dubbo 服务
*/
@DubboService(methods = {@Method(name = "getById", timeout = 3000)})
public class UserServiceImpl implements UserService {

@Override
public User getById(Long id) {
return new User(id, "Peter", 18);
}

}
  • 服务消费者配置超时时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
@RequestMapping("/user")
public class UserController {

/**
* 引用 Dubbo 服务
*/
@DubboReference(methods = {@Method(name = "getById", timeout = 3000)})
private UserService userService;

@GetMapping("/getById/{id}")
public User getById(@PathVariable("id") Long id) {
return userService.getById(id);
}

}

版本说明

Dubbo 从 2.7.7 版本开始提供 @DubboService@DubboReference 注解,目的是为了替代 Dubbo 旧版本的 @Service@Reference 注解。

XML 配置方式

接口级别配置超时时间

  • 服务提供者配置超时时间(推荐)
1
2
3
4
5
<!-- 服务实现类 Bean -->
<bean id="demoService" class="com.clay.dubbo.provider.service.DemoServiceImpl"/>

<!-- 声明要暴露的服务 -->
<dubbo:service interface="com.clay.dubbo.service.DemoService" ref="demoService" timeout="1000"/>
  • 服务消费者配置超时时间
1
2
<!-- 引用远程服务 -->
<dubbo:reference id="demoService" interface="com.clay.dubbo.service.DemoService" timeout="1000"/>

方法级别配置超时时间

  • 服务提供者配置超时时间(推荐)
1
2
3
4
5
6
7
8
<!-- 服务实现类 Bean -->
<bean id="demoService" class="com.clay.dubbo.provider.service.DemoServiceImpl"/>

<!-- 声明要暴露的服务 -->
<dubbo:service interface="com.clay.dubbo.service.DemoService" ref="demoService">
<!-- 方法级别单独配置超时时间 -->
<dubbo:method name="getById" timeout="5000"/>
</dubbo:service>
  • 服务消费者配置超时时间
1
2
3
4
5
<!-- 引用远程服务 -->
<dubbo:reference id="demoService" interface="com.clay.dubbo.service.DemoService">
<!-- 方法级别单独配置超时时间 -->
<dubbo:method name="getById" timeout="3000"/>
</dubbo:reference>

重试次数

特性说明

特别注意

  • Dubbo 的重试次数通常是配合超时时间(或者集群容错策略 FailoverCluster )一起使用的,当接口调用超时(或者调用出错),就重试 N 次接口调用。
  • Dubbo 的重试次数(默认是重试 2 次,加上第一次接口调用,一共会调用 3 次 接口),支持在服务消费者和服务提供者两边进行配置。
  • 如果服务消费者和服务提供者都配置了重试次数,那么服务消费者的配置优先级更高。
  • 由于服务提供者最了解接口的业务逻辑,因此在企业开发中,建议在服务提供者中配置重试次数。
  • 特别注意,只有幂等接口(比如查询、更改、删除接口)才建议设置重试次数,非幂等接口(比如新增接口)不建议设置重试次数,否则会出现数据一致性问题,例如插入重复数据。

注解配置方式

  • 服务提供者配置重试次数(推荐)
1
2
3
4
5
6
7
8
9
10
11
12
/**
* 暴露 Dubbo 服务
*/
@DubboService(timeout = 1000, retries = 3)
public class UserServiceImpl implements UserService {

@Override
public User getById(Long id) {
return new User(id, "Peter", 18);
}

}
  • 服务消费者配置重试次数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
@RequestMapping("/user")
public class UserController {

/**
* 引用 Dubbo 服务
*/
@DubboReference(timeout = 1000, retries = 3)
private UserService userService;

@GetMapping("/getById/{id}")
public User getById(@PathVariable("id") Long id) {
return userService.getById(id);
}

}

版本说明

Dubbo 从 2.7.7 版本开始提供 @DubboService@DubboReference 注解,目的是为了替代 Dubbo 旧版本的 @Service@Reference 注解。

XML 配置方式

  • 服务提供者配置重试次数(推荐)
1
2
3
4
5
<!-- 服务实现类 Bean -->
<bean id="demoService" class="com.clay.dubbo.provider.service.DemoServiceImpl"/>

<!-- 声明要暴露的服务 -->
<dubbo:service interface="com.clay.dubbo.service.DemoService" ref="demoService" timeout="1000" retries="3"/>
  • 服务消费者配置重试次数
1
2
<!-- 引用远程服务 -->
<dubbo:reference id="demoService" interface="com.clay.dubbo.service.DemoService" timeout="1000" retries="3"/>

负载均衡

特性说明

Dubbo 提供了五种负载均衡策略,如下所示:

负载均衡策略说明适用场景
RandomLoadBalance 随机(默认策略),支持按权重设置随机概率适用于请求量分散、服务性能相近的场景,能保证简单有效的负载均衡效果
RoundRobinLoadBalance 轮询,支持按公约后的权重设置轮询比率适用于服务节点性能相近、需要保证调用次数均匀的场景
LeastActiveLoadBalance 最少活跃调用数,支持相同活跃数的权重随机适用于服务性能差异较大或请求响应时间差异较大的场景,能提高请求分配效率
ConsistentHashLoadBalance 一致性哈希,相同参数的请求总是发送到同一个服务提供者适用于需要保证请求一致性的场景,例如:缓存服务或用户会话粘性
ShortestResponseLoadBalance 最短响应时间优先,选择响应时间最短的服务提供者适用于请求响应时间差异较大,且希望优先使用低延迟服务节点的场景

特别注意

  • Dubbo 的负载均衡策略支持在服务消费者和服务提供者两边进行配置,但是服务消费者的配置优先级更高,即:
  • (1) 如果服务消费者明确配置了负载均衡策略,则会使用服务消费者的策略。
  • (2) 如果服务消费者未配置负载均衡策略,则会使用服务提供者通过 @DubboService 注解指定的负载均衡策略。
  • (3) 如果服务消费者和服务提供者都未配置负载均衡策略,则会使用 Dubbo 的全局默认负载均衡策略(RandomLoadBalance)。

提示

Dubbo 的负载均衡策略都统一实现了 AbstractLoadBalance 接口,比如常见的实现类有:RandomLoadBalanceRoundRobinLoadBalanceLeastActiveLoadBalance 等。

注解配置方式

  • 第一步:服务消费者设置负载均衡策略,可选策略包括:randomroundrobinleastactiveconsistenthashshortestresponse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
@RequestMapping("/user")
public class UserController {

/**
* 引用 Dubbo 服务
*/
@DubboReference(loadbalance = "random")
private UserService userService;

@GetMapping("/getById/{id}")
public User getById(@PathVariable("id") Long id) {
return userService.getById(id);
}

}
  • 第二步:若需要设置负载均衡策略的权重,则可以在服务提供者中设置 weight 属性
1
2
3
4
5
6
7
8
9
10
11
12
/**
* 暴露 Dubbo 服务
*/
@DubboService(weight = 100)
public class UserServiceImpl implements UserService {

@Override
public User getById(Long id) {
return new User(id, "Peter", 18);
}

}

XML 配置方式

  • 第一步:服务消费者设置负载均衡策略,可选策略包括:randomroundrobinleastactiveconsistenthashshortestresponse
1
2
<!-- 引用远程服务 -->
<dubbo:reference id="demoService" interface="com.clay.dubbo.service.DemoService" loadbalance="random"/>
  • 第二步:若需要设置负载均衡策略的权重,则需要在服务提供者中设置 weight 属性
1
2
3
4
5
<!-- 服务实现类 Bean -->
<bean id="demoService" class="com.clay.dubbo.provider.service.DemoServiceImpl"/>

<!-- 声明要暴露的服务 -->
<dubbo:service interface="com.clay.dubbo.service.DemoService" ref="demoService" weight="100"/>

集群容错(重试)

特性说明

  • Dubbo 提供了八种集群容错(重试)策略,如下所示:
集群容错策略策略名称策略说明适用场景
Failover 故障转移默认策略,当出现服务调用失败,重试调用其它服务器,默认重试 2 次,使用 retries 属性配置重试次数通常用于读操作(幂等操作),如查询数据时可以容忍偶尔失败并重试的场景
Failfast 快速失败消费者只发起一次调用,若失败则立即抛出异常,类似于 Failover 集群容错策略中重试次数设置为 0 的情况通常用于写操作(非幂等操作),如数据插入操作,失败时不应该重试
Failsafe 失败安全当消费者调用提供者出现异常时,只会打印异常,而不会抛出异常,即直接忽略本次消费操作,返回一个空结果适用于不重要的操作,如日志记录或监控信息上报,出现失败不影响整体业务逻辑
Failback 失败自动恢复在消费者调用失败后,返回一个空结果。Dubbo 会在内存中记录下(非持久化)该失败请求,并通过定时任务对失败的调用进行重试,且重试间隔默认是 5 秒(不可配置)通常用于消息通知操作,如异步通知,失败后可自动补偿
Forking 并行调用消费者对于同一服务会并行调用多个提供者服务器,只要有一个成功就调用结束,并返回结果通常用于实时性要求较高的读操作,但需要浪费更多的服务资源,可通过 forks = "2" 来设置最大并行数
Broadcast 广播调用通过广播调用所有提供者,逐个调用,任意一个提供者报错则报错适用于更新配置或通知所有服务提供者的场景,如缓存更新或者服务健康检查
ZoneAware 区域感知集群当部署了多个机房或区域(Zone)时,优先调用同一机房的服务提供者,以降低跨区调用延迟和网络风险适用于多区域部署场景,优先减少跨区域网络延迟的情况下实现高效负载均衡
Mergeable 结果合并集群调用多个服务提供者,并将多个服务提供者的调用结果进行合并,最终返回合并后的结果适用于需要聚合结果的场景,例如分布式查询、汇总统计等操作

特别注意

Dubbo 的集群容错策略是在服务消费者中配置的。虽然服务提供者使用的 @DubboService 注解也可以配置 cluster 属性,但该 cluster 属性是用来声明服务的分组行为,通常配合服务分组或路由规则一起使用。简而言之,服务提供者的 @DubboService 注解的 cluster 属性与消费者端的集群容错策略无关,它并不直接控制服务消费者的集群容错策略,而是影响服务的分发和消费方式。

提示

  • Dubbo 的集群容错策略都统一实现了 AbstractCluster 接口,比如常见的实现类有:FailoverClusterFailfastClusterFailsafeClusterFailbackCluster 等。
  • FailbackCluster(失败自动恢复)的使用问题
    • 问题描述:
      • 调用失败的记录只存储在内存中,应用重启或进程崩溃后,重试记录将会丢失,导致重试机制失效。
      • 这种重试机制不适用于核心业务,比如支付交易、订单创建、库存扣减、用户积分更新等。
    • 问题解决:
      • 第一种方案:
        • Dubbo 调用改为消息驱动,使用 MQ 做调用的缓冲与重试。
          • (1) 生产者不直接调用 Dubbo 服务,而是先将消息写入 MQ 中;
          • (2) 由一个消息消费服务订阅 MQ 消息,然后执行 Dubbo RPC 调用(基于 Dubbo 原生 API 实现泛化调用);
          • (3) 如果 Dubbo RPC 调用失败,可以将消息写入到延迟队列中,直到 RPC 调用成功;
          • (4) 如果重试调用次数达到最大重试次数,则将消息写入死信队列。
          • (5) 为了避免重复调用,需要实现幂等性,比如使用数据库唯一约束(如 requestId 字段)、Redis 缓存(如 SETNX)等。
      • 第二种解决方案:
        • (1) 自定义扩展 FailbackCluster 的实现;
        • (2) 将失败记录写入外部存储(如 Redis、DB);
        • (3) 创建后台线程,每隔固定时间扫描一次外部存储,尝试重新调用 Dubbo 服务(基于 Dubbo 原生 API 实现泛化调用);
        • (4) 当重试调用成功返回时,将对应的失败记录从外部存储中删除,避免重复调用和数据堆积;
        • (5) 应用重启后重新加载未完成的失败记录,并继续由后台线程执行重试逻辑;
        • (6) 为了避免重复调用,需要实现幂等性,比如使用数据库唯一约束(如 requestId 字段)、Redis 缓存(如 SETNX)等。
    • 方案对比:
      对比维度 MQ(Kafka / RabbitMQ / RocketMQ)Redis / MySQL
      数据持久化内置持久化到 Broker 持久化到外部存储,需要自己实现
      应用重启恢复重启后仍可消费未完成消息重启后可读取失败记录,依赖自定义逻辑
      重试保障原生支持延迟重试和死信队列需定时任务扫描和手动实现延迟 / 死信机制
      吞吐能力高,支持大规模并发中等,定时扫描会成为性能瓶颈
      延迟控制原生支持延迟队列延迟不可控,依赖扫描频率
      实现复杂度中等,需要部署 MQ,但重试逻辑成熟低 - 中,不依赖额外中间件,但需自己实现重试和死信机制
      适用场景核心业务,如订单、支付、交易弱异步业务,如日志、通知、监控埋点等,可容忍一定延迟或失败
      维护成本低,MQ 自带可靠机制高,定时任务、重试逻辑和死信处理需自行维护

Dubbo 的泛化调用是什么

普通的 Dubbo 调用依赖接口类,会进行编译期类型检查,适合直接业务调用。而泛化调用则不依赖接口类,只通过接口名称和方法信息在运行时进行调用,参数类型通过字符串描述,适合消息化、动态调用、异步或重试场景。

注解配置方式

  • 服务消费者设置集群容错策略,可选模式包括:failoverfailfastfailsafefailbackforkingbroadcastavailablemergeable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController
@RequestMapping("/user")
public class UserController {

/**
* 引用 Dubbo 服务
*/
@DubboReference(cluster = "failfast")
private UserService userService;


@GetMapping("/getById/{id}")
public User getById(@PathVariable("id") Long id) {
return userService.getById(id);
}

}

XML 配置方式

  • 服务消费者设置集群容错策略,可选模式包括:failoverfailfastfailsafefailbackforkingbroadcastavailablemergeable
1
2
<!-- 引用远程服务 -->
<dubbo:reference id="demoService" interface="com.clay.dubbo.service.DemoService" cluster="failfast"/>

服务降级(Mock)

特性说明

在 Dubbo 中有一种机制可以实现轻量级的服务降级(也叫 “本地伪装”)。Mock 是 Stub 的一个子集,便于服务提供者在客户端执行容错逻辑,因此经常需要在出现 RpcException(比如网络失败,超时等)时进行容错,而在出现业务异常(比如登录用户名 / 密码错误)时不需要容错。如果用 Stub,可能就需要捕获并依赖 RpcException 类,而用 Mock 就可以不依赖 RpcException,因为它的约定就是只有出现 RpcException 时才执行。

特别注意

  • Dubbo Mock 是一种服务降级机制。它会在 RPC 远程调用失败后,根据配置自动触发,用于服务降级(返回兜底数据)或者进行本地模拟测试。
  • Mock 并不是在 "集群容错机制无法处理故障" 时才触发,而是 Dubbo 独立提供的服务降级机制,可与集群容错机制结合使用。

使用场景

本地伪装常被用于服务降级。比如某鉴权服务,当服务提供者全部挂掉后,假如此时服务消费者发起了一次远程调用,那么本次调用将会失败并抛出一个 RpcException 异常。为了避免出现这种直接抛出异常的情况出现,那么客户端就可以利用本地伪装来提供 Mock 数据返回授权失败。其他使用场景包括:

  • 某服务或接口负荷超出最大承载能力范围,需要进行降级应急处理,避免系统崩溃。
  • 调用的某非关键服务或接口暂时不可用时,返回模拟数据或空,业务还能继续可用。
  • 降级非核心业务的服务或接口,腾出系统资源,尽量保证核心业务的正常运行。
  • 某上游基础服务超时或不可用时,执行能快速响应的降级预案,避免服务整体雪崩。

使用方式

Dubbo 支持以下几种方式来使用 Mock:

  • (1) 用 return 来返回一个字符串表示的对象,作为 Mock 的返回值

    • 比如:<dubbo:reference interface="com.foo.BarService" mock="return null" />,表示 RPC 调用失败时直接返回 null 给服务消费者
    • 合法的字符串可以是:
      • empty:代表空,返回基本类型的默认值、集合类的空值、自定义实体类的空对象,如果返回值是一个实体类,那么此时返回的将会是一个属性都为默认值的空对象而不是 null
      • null:返回 null
      • true:返回 true
      • false:返回 false
      • JSON 字符串:返回反序列化 JSON 串后所得到的对象
  • (2) 使用 throw 来返回一个 Exception 对象,作为 Mock 的返回值

    • 当调用出错时,抛出一个默认的 RPCException,比如:<dubbo:reference interface="com.foo.BarService" mock="throw"/>
    • 当调用出错时,抛出指定的 Exception,比如:<dubbo:reference interface="com.foo.BarService" mock="throw com.foo.MockException"/>。特别注意,自定义异常必须拥有一个入参为 String 的构造函数,该构造函数将用于接受异常信息。
  • (3) 使用 forcefail 关键字来配置 Mock 的行为

    • force:
      • 代表强制使用 Mock 行为,在这种情况下不会走 RPC 远程调用。
      • forcefail 一样都支持与 throw 或者 return 组合使用。
      • 比如:mock = "force:return null" 表示服务消费者对该服务的方法调用都直接返回 null 值,不发起远程调用。用于避免在不重要服务不可用时,对服务消费者产生负面。
    • fail:
      • 正常情况下与默认行为一致,只有当 RPC 远程调用发生错误时才会使用 Mock 行为。
      • 也就是说,配置的时候其实是可以不使用 fail 关键字的,直接使用 throw 或者 return 就可以了。
      • 比如:mock = "fail:return null" 表示服务消费者对该服务的方法调用出现失败时返回 null 值,不抛出异常。用于容忍不重要服务不稳定时,对服务消费者产生负面影响。最终效果类似使用 FailsafeCluster 集群容错策略。
    • 使用举例:
      • 强制返回指定值:<dubbo:reference interface="com.foo.BarService" mock="force:return fake"/>
      • 强制抛出指定异常:<dubbo:reference interface="com.foo.BarService" mock="force:throw com.foo.MockException"/>
      • 调用失败时返回指定值:<dubbo:reference interface="com.foo.BarService" mock="fail:return fake"/>,等价于 mock="return fake"
      • 调用失败时抛出指定异常:<dubbo:reference interface="com.foo.BarService" mock="fail:throw com.foo.MockException"/>,等价于 mock="throw com.foo.MockException"
  • (4) 在方法级别配置 Mock

    • Mock 支持在方法级别上指定,假设 com.foo.BarService 上有好几个方法,可以单独为 sayHello() 方法指定 Mock 行为。
    • 配置示例如下所示,只要 sayHello() 方法被调用到时,强制返回 “fake”,不走 RPC 远程调用:
      1
      2
      3
      <dubbo:reference id="demoService" check="false" interface="com.foo.BarService">
      <dubbo:parameter key="sayHello.mock" value="force:return fake"/>
      </dubbo:reference>
  • (5) 自定义 Mock 的行为

    • 在 Java 接口所在的包下创建一个 Mock 实现类,比如实现 BarService 接口和实现 sayHello() 方法,并且拥有一个无参构造函数,Java 代码和 XML 配置如下所示。
    • 特别注意,如果没有在 XML 配置文件或者注解中显式指定 Mock 实现类,那么就需要保证 Mock 实现类的全限定类名符合 原接口的全限定名 + Mock 的格式,例如 com.foo.BarServiceMock,否则将会 Mock 失败。
    • 1
      2
      3
      4
      5
      6
      public class BarServiceMock implements BarService {
      public String sayHello(String name) {
      // 自定义服务降级的逻辑,比如可以返回兜底数据,此方法只在出现 RpcException 时才会被执行
      return "容错数据";
      }
      }
      1
      2
      3
      4
      5
      <!-- 指定 Mock 实现类 -->
      <dubbo:reference interface="com.foo.BarService" mock="com.foo.BarServiceMock" />

      <!-- 或者,默认会自动去找 Mock 实现类 com.foo.BarServiceMock -->
      <dubbo:reference interface="com.foo.BarService" mock="true" />
  • (6) 配合 Dubbo-Admin 使用 Mock,实现 Mock 规则的动态更改,详细的使用介绍请看 这里

特别注意

  • 在 Dubbo 中,服务降级是通过 mock 属性来实现,该属性通常是配置在服务消费者中的,不应该配置在服务提供者中,比如 @DubboReference(mock="force:return fake")
  • 服务降级逻辑应该完全由服务消费者端负责的,因为服务消费者需要决定在服务不可用时如何继续处理。

使用案例

注解配置方式
  • 服务消费者配置服务降级
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
@RequestMapping("/user")
public class UserController {

/**
* 引用 Dubbo 服务
*/
@DubboReference(mock = "fail:return null")
private UserService userService;

@GetMapping("/getById/{id}")
public User getById(@PathVariable("id") Long id) {
return userService.getById(id);
}

}
XML 配置方式
  • 服务消费者配置服务降级
1
2
<!-- 引用远程服务 -->
<dubbo:reference id="demoService" interface="com.clay.dubbo.service.DemoService" mock = "fail:return null"/>
Dubbo-Admin 配置方式
  • 概念介绍

    • Dubbo-Admin 支持以服务方法的维度设置服务降级(Mock)规则,包括设置返回模拟数据、动态启用 / 禁用规则等。
    • Dubbo 的服务降级(Mock)支持与 Dubbo-Admin 配合使用,这样就可以通过 Dubbo-Admin 的 UI 界面动态配置 Mock 规则,即达到动态实现服务降级的目的。
  • 使用条件

    • 要求 Dubbo 的版本必须大于等于 3.0.0,否则无法配合 Dubbo-Admin 正常使用 Mock
    • 服务消费者引入 Maven 依赖 dubbo-mock-admin,官方文档说明请看 这里 的介绍
    • 服务消费者启动时必须设置 JVM 参数 -Denable.dubbo.admin.mock=true,目的是启用 Dubbo-Admin Mock 功能
    • 启动 Dubbo-Admin 后,在 Web 控制台界面中的 服务 Mock -> 规则列表 菜单下添加自定义的 Mock 规则(如下图所示)
  • 注意事项

    • 在 Dubbo 中,服务降级是通过 mock 属性来实现,该属性通常是配置在服务消费者中的,不应该配置在服务提供者中,比如 @DubboReference(mock="force:return fake")
    • 在 Dubbo Admin 的 服务 Mock 管理界面里,填写的 规则内容 其实就是 Mock 执行逻辑的正文部分,Dubbo Admin 本身已经在内部为该规则内容指定了 force:return 的处理方式
    • 在 Dubbo Admin 中,如果 规则内容 中包含 force: 前缀,会被当作普通字符串处理,而不会被当作 Mock 指令;因此填写 规则内容 时不需要使用 force: 或者 fail: 前缀,直接填写要返回的数据即可
  • 案例代码

    • Dubbo-Admin + Mock 配合使用的完整案例代码可以直接从 GitHub 下载对应章节 dubbo-lesson-10dubbo-lesson-11

全局(默认)配置

YML 配置方式

  • 指定全局默认超时时间,对所有服务生效
1
2
3
4
5
6
7
dubbo:
# 统一设置服务提供者的超时时间(单位:毫秒)
provider:
timeout: 1000
# 统一设置服务消费者的超时时间(单位:毫秒)
consumer:
timeout: 1000

XML 配置方式

  • 指定全局默认超时时间,对所有服务生效
1
2
3
4
5
<!-- 统一设置服务提供者的超时时间(单位:毫秒) -->
<dubbo:provider timeout="1000"/>

<!-- 统一设置服务消费者的超时时间(单位:毫秒) -->
<dubbo:consumer timeout="1000"/>
  • 基于分组的默认值,对部分服务生效
1
2
3
4
5
6
7
8
9
10
<!-- 分组设置服务提供者的超时时间(单位:毫秒) -->
<dubbo:provider timeout="1000">
<dubbo:service interface="com.clay.api.HelloService" ref="helloService"/>
<dubbo:service interface="com.clay.api.HelloService2" ref="helloService2"/>
</dubbo:provider>

<dubbo:provider timeout="3000">
<dubbo:service interface="com.clay.api.DemoService" ref="demoService"/>
<dubbo:service interface="com.clay.api.DemoService2" ref="demoService2"/>
</dubbo:provider>

参考资料