dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线前,能及早发现问题,默认check="true"

如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭检查,否则服务临时不可用时会抛出异常,拿到 null 引用,如果check="false",总是会返回引用,当服务恢复时,能自动连上。

比如对一些不关心的服务,或者服务之间出现了相互依赖必须有一方先启动时,你可以关闭检查避免异常。

1. 场景描述

假设现有两个已知的服务:用户中心服务、订单中心服务。它们作为服务提供者分别向 dubbo 注册了自己。用户中心服务中的UserServiceImpl调用了订单中心服务的OrderServiceImpl,如下:

1
2
3
4
5
6
7
8
public class OrderServiceImpl implements OrderService {
@Override
public void findByUserIdAndOrderStatus(Integer userId, String orderStatus) {
// do something
}
}
1
2
3
4
5
6
7
8
9
10
11
public class UserServiceImpl implements UserService {
private OrderService orderService;
@Override
public void findPaidOrdersById(Integer id) {
// do something
orderService.findByUserIdAndOrderStatus(id, "PAID");
}
}

2. XML 配置方式

订单中心服务配置信息的代码片段:

1
2
3
4
5
<!-- 声明 Bean -->
<bean id="orderService" class="org.fanlychie.service.OrderServiceImpl" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="org.fanlychie.service.OrderService" ref="orderService" />

用户中心服务配置信息的代码片段:

1
2
3
4
5
6
7
8
9
10
11
<!-- 声明引用的服务, check 设为 false 以关闭服务的启动时检查, 避免服务启动顺序引发的异常 -->
<dubbo:reference id="orderService" interface="org.fanlychie.service.OrderService" check="false" />
<!-- 声明 Bean -->
<bean id="userService" class="org.fanlychie.service.UserServiceImpl">
<!-- 声明依赖的服务 -->
<property name="orderService" ref="orderService" />
</bean>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="org.fanlychie.service.UserService" ref="userService" />

<dubbo:reference>的 check 属性设为 false 以关闭服务的启动时检查,否则服务的启动顺序不当会直接导致服务启动不了。如check=true(默认)若先启动用户中心服务会报以下异常导致服务启动失败:

1
java.lang.IllegalStateException: Failed to check the status of the service ...

在用户心中调用订单中心的服务示例代码片段,相关的依赖需要通过 setter 方法注入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class UserServiceImpl implements UserService {
private OrderService orderService;
@Override
public void findPaidOrdersById(Integer id) {
// do something
orderService.findByUserIdAndOrderStatus(id, "PAID");
}
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
}

3. 注解的方式

订单中心的服务接口使用com.alibaba.dubbo.config.annotation.@Service注解直接暴露服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
package org.fanlychie.service;
import com.alibaba.dubbo.config.annotation.Service;
@Service
public class OrderServiceImpl implements OrderService {
@Override
public void findByUserIdAndOrderStatus(Integer userId, String orderStatus) {
// do something
}
}

用户中心的服务接口使用com.alibaba.dubbo.config.annotation.@Service注解暴露服务,并使用使用com.alibaba.dubbo.config.annotation.@Reference注解引用订单中心的接口服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package org.fanlychie.service;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
@Service
public class UserServiceImpl implements UserService {
@Reference
private OrderService orderService;
@Override
public void findPaidOrdersById(Integer id) {
// do something
orderService.findByUserIdAndOrderStatus(id, "PAID");
}
}

引用的服务的属性check应设为 false 以关闭服务的启动时检查,避免服务启动顺序引发的异常。使用注解@Reference(check = false)的方式是无效的,需要在调用方(本文为用户中心)的配置文件中添加:

1
2
<!-- 关闭引用服务的启动时检查 -->
<dubbo:consumer check="false" />

参考文档文献链接:启动时检查