Dubbo 服务启动检查

 

前言

大家好,今天开始给大家分享 — Dubbo 专题之 Dubbo 服务启动检测。在前面的章节中我们介绍了 Dubbo服务配置,在这个章节中我们会介绍服务启动检查。那么什么是服务启动检测呢?顾名思义就是服务启动时执行检查,那么检查什么。这样做有什么使用场景呢?那就让我们快速开始吧!

 

1. 服务检测简介

在 Dubbo 中提供了多种服务检查,分别是:服务提供者检查、注册中心检查 。我们可以通过配置的方式进行切换是否开启检查,默认是true下面通过三种配置方式进行说明:

1.1 xml配置方式

  1. 关闭依赖服务检查
    关闭某个服务的启动时检查
<dubbo:reference interface="com.foo.BarService" check="false" />

关闭所有服务的启动时检查

<dubbo:consumer check="false" />
  1. 关闭注册中心启动时检查
<dubbo:registry check="false" />

1.2 通过属性配置

#关闭指定接口服务检查
dubbo.reference.com.muke.dubbocourse.serviceconfig.api.BookFacade.check=false
#关闭所有引用服务检查
dubbo.reference.check=false
#关闭所有服务的启动时检查
dubbo.consumer.check=false
#关闭注册中心启动时检查 
dubbo.registry.check=false

1.3 通过 JVM 参数

#关闭指定接口服务检查
java -Ddubbo.reference.com.muke.dubbocourse.serviceconfig.api.BookFacade.check=false
#关闭所有引用服务检查
java -Ddubbo.reference.check=false
#关闭所有服务的启动时检查
java -Ddubbo.consumer.check=false 
#关闭注册中心启动时检查 
java -Ddubbo.registry.check=false

Tips:dubbo.reference.check=false强制改变所有 referencecheckdubbo.consumer.check=false是设置 check<dubbo:reference check="true"/>不会受影响。dubbo.registry.check=false前面两个都是指订阅成功,但提供者列表是否为空是否报错,如果注册订阅失败时,也允许启动,需使用此选项,将在后台定时重试。

 

2. 启动时服务检查作用

Dubbo 服务会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 容器初始化完成,以便上线时,能及早发现问题,默认 check="true",即默认情况当 Dubbo 服务启动时候会去检查依赖服务是否可用。我们可以通过 check="false"check,否则服务临时不可用时,会抛出异常,拿到 nullcheck="false",总是会返回引用,当服务恢复时,能自动连上。

 

3. 示例演示

下面我们通过一个获取书列表的例子来进行演示,代码结构如下:

这里主要看消费端的 xml 配置文件dubbo-consumer-xml.xml,我们在<dubbo:reference>标签中指定了

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
      xmlns="http://www.springframework.org/schema/beans"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
      http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

   <dubbo:application name="demo-consumer" logger="log4j"/>

   <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
   <!--   <dubbo:consumer check="false" />-->
   <!--   <dubbo:registry check="false" />-->

   <!--当check="false"是服务提供者未启动不会报错 注意 :这里必须配置init="true"才能达到检查效果-->
   <dubbo:reference id="bookFacade" init="true" check="true"
                    interface="com.muke.dubbocourse.common.api.BookFacade"></dubbo:reference>

</beans>

init="true"check="true"属性来确保在消费者服务启动时检查com.muke.dubbocourse.common.api.BookFacade服务提供者存在否则会抛出异常。

 

4. 原理分析

我们使用的<dubbo:reference>@Reference@DubboReference引用 Dubbo 暴露的服务时都会被解析为ReferenceBean简化后的源码:

public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
       ApplicationContextAware, InitializingBean, DisposableBean {

  @Override
   @SuppressWarnings({"unchecked"})
   public void afterPropertiesSet() throws Exception {

       // Initializes Dubbo's Config Beans before @Reference bean autowiring
       prepareDubboConfigBeans();

       // lazy init by default.
       if (init == null) {
           init = false;
      }

       // 判断是否初始化代理对象 
       if (shouldInit()) {
           //获取代理对象
           getObject();
      }
  }

   @Override
   public void destroy() {
       // do nothing
  }
}

从上面源码可以知道ReferenceBean实现了InitializingBean接口,属性 Spring 的朋友都知道这是 Bean 生命周期回调接口。当我们的 Bean 在Spring 管理的生命周期中被回调afterPropertiesSet方法,此方法init标记来判断是否初始化取代理对象(这个必须配置),从而触发创建代理对象。在创建代理对象时com.alibaba.dubbo.config.ReferenceConfig#createProxy方法中会根据check="true"配置判断提供者服务是否存在,不存在则触发异常。代码如下:

Boolean c = check;
       if (c == null && consumer != null) {
           c = consumer.isCheck();
      }
       if (c == null) {
           c = true; // default true
      }
       if (c && !invoker.isAvailable()) {
           // make it possible for consumer to retry later if provider is temporarily unavailable
           initialized = false;
           throw new IllegalStateException("Failed to check the status of the service " + interfaceName + ". No provider available for the service " + (group == null ? "" : group + "/") + interfaceName + (version == null ? "" : ":" + version) + " from the url " + invoker.getUrl() + " to the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());
      }

 

5. 小结

在本小节中我们主要学习了 Dubbo 中的3种服务启动检查配置方式,分别从 XML 配置、属性配置、JVM参数等方式进行简单的配置,我们可以总结道是否需要检查依赖服务根据我们具体的业务场景来决定,需要在启动时候就要检查依赖服务是否存储则配置 check="true"否则配置 check="false"

本节课程的重点如下:

  1. 理解 Dubbo 中启动服务依赖检查
  2. 了解什么场景需要依赖检查
  3. 了解怎么配置服务以来检查
  4. 了解了启动依赖检查的实现原理

.