欢迎访问Spring Cloud中国社区

《重新定义Spring Cloud实战》由Spring Cloud中国社区倾力打造,基于Spring Cloud的Finchley.RELEASE版本,本书内容宽度足够广、深度足够深,而且立足于生产实践,直接从生产实践出发,包含大量生产实践的配置。欢迎加微信Software_King进群答疑,国内谁在使用Spring Cloud?欢迎登记

spring consul 健康检查与 consul 版本匹配问题

bishion · 5月前 · 2326 ·

问题描述

consul 升级后,原有的项目健康检查 /health 通不过,报 Data must not be null 的错误

问题排查

健康检查源码:ConsulHealthIndicator.class

protected void doHealthCheck(Health.Builder builder) throws Exception {
    try {
        Response<Self> self = consul.getAgentSelf();  // 请求接口:domain:port/v1/agent/self
        Config config = self.getValue().getConfig();
        Response<Map<String, List<String>>> services = consul.getCatalogServices(QueryParams.DEFAULT);
        builder.up()
                .withDetail("services", services.getValue())
                .withDetail("advertiseAddress", config.getAdvertiseAddress()) // 该配置为空,因而报了异常
                ******
    }
    catch (Exception e) {
        builder.down(e);
    }
}

分析

经源码得知,consul 的健康检测是去拿 agent 的基础配置,继而根据基础配置的一些字段来判断 consul 是否正常运行
然而,consul 的1.0.0 版本以后,/agent/self 接口返回的信息中便没有了 advertiseAddress 信息,于是健康检查就报了异常

解决方案

方案一:升级 spring-cloud-consul 到 1.3.0.RELEASE 版本

protected void doHealthCheck(Health.Builder builder) throws Exception {
    try {  
        Response<String> leaderStatus = consul.getStatusLeader(); // 请求接口:domain:port/v1/status/leader
        Response<Map<String, List<String>>> services = consul.getCatalogServices(QueryParams.DEFAULT);
        builder.up()
                .withDetail("leader", leaderStatus.getValue()) // 只查看 leader 信息,不再拿别的参数了
                .withDetail("services", services.getValue());
    }
    catch (Exception e) {
        builder.down(e);
    }
}

优点

  1. spring 换了个相对稳定的接口做健康检查,以应对将来可能的接口变化
  2. 之后的一段时间,consul 的升级应该不会影响到健康检查

缺点

  1. spring-cloud-consul 升级到 1.3.0.RELEASE,意味着 spring-cloud 要升级到 Edgware.SR1,对于很多老项目来说,代价太大
  2. 没有了,第一条已经致命了

方案二:关闭 consul 的健康检查配置

management.health.consul.enabled=false

优点

  1. 快速修改
  2. 通过 config-server 可以实现热加载,不需上线

缺点

  1. 健康检查排除掉 consul,有一定的隐患
  2. 该配置并不支持 spring-cloud-consul 的 1.1.2.RELEASE 以前的版本

分析

因为 consul 作为注册中心,挂掉的几率还是很小的,将“关闭对 consul 的健康检查”作为临时解决方案是可行的
然而 1.1.2.RELEASE 版本以前的 spring-cloud-consul,是强制对 consul 做健康检查的,并没有开放