关于Spring Cloud健康检查的陷阱

 更新时间:2021年07月23日 09:27:35   作者:tom3mao  
这篇文章主要介绍了关于Spring Cloud健康检查的陷阱,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

SpringCloud健康检查的陷阱

健康检查

基于Spring Boot Actuator的健康检查是Spring Cloud微服务的必备组件,用来确保我们的服务是否可用。

引入 Spring Boot Actuator后,通过http://ip:port/health ,可以看到 HealthEndPoint 给我们提供默认的监控结果,包含磁盘检测和数据库检测。如下

{
    "status": "UP",
    "diskSpace": {
        "status": "UP",
        "total": 398458875904,
        "free": 315106918400,
        "threshold": 10485760
    },
    "db": {
        "status": "UP",
        "database": "MySQL",
        "hello": 1
    }
}

排除不必要的健康检查项

有一天调用方突然反馈调不通我们的服务。查看Eureka控制台,发现服务状态是UP。查看服务进程一切正常。束手无策之际,忽然想到会不会是健康检查在作怪,因为Eureka Client判断服务可用与否的依据就是健康检查。而Spring Boot Actuator所有的监控项中的任何一个健康状态是DOWN,那个整体应用的健康状态也是DOWN,这时候调用方就把服务当作不可用。

再次查看http://ip:port/health,果然发现有一项邮件健康检查挂了。

最近项目引入了spring-boot-starter-mail,实现发送邮件的功能。

邮箱服务器挂了,造成整个服务的监控检查状态是DOWN。

{
  "status": "DOWN",
  "mail": {
    "status": "DOWN",
    "location": "email-smtp.test.com:-1",
    "error": "javax.mail.AuthenticationFailedException: 535 Authentication Credentials Invalid\n"
  },
  "diskSpace": {
    "status": "UP",
    "total": 266299998208,
    "free": 146394308608,
    "threshold": 10485760
  },
  "hystrix": {
    "status": "UP"
  }
}

由于邮件发送不是核心功能,可以把非核心组件从健康检查中排除,避免造成整个服务不可用。

通过如下配置关闭邮箱健康检查。

management.health.mail.enabled=false

springcloud-health检查超时引发的大坑

0. 前提约定

service:只一个微服务

server:只提供一个微服务的app,一般一个service有多个server。

1. 问题介绍

线上springcloud遇到这样的问题:某些时候会移除某个service的所有server。

2. 原因分析

springcloud中默认使用springboot-actauctor的health-url作为健康检测,默认检查的超时时间为10s,如果生产环境遇到网络、db、redis慢或者挂了等问题,会导致health检查请求超时,springcloud注册中心会认为该server异常,从而将server状态变更为critial,服务调用方(feign)会将该异常server从负载中移除(HealthServiceServerListFilter)。

如果遇到某网段或更大规模的网络、db等问题,会导致某个service所有server都被注册中心移除,导致该service不可用。

但是实际上该server只是存在部分问题例如:仅仅是db或redis慢,不算不可用,但还是被注册中心强制摘除了。

3. 解决办法

3.1 通用解决办法

关闭health检查,永远返回up状态,只要程序正常启动就认为可以提供正常服务。

如下是项目模板输出默认的health检查结果:

{
 "description": "",
 "status": "UP",
 "diskSpace": {
  "description": "",
  "status": "UP",
  "total": 50715856896,
  "free": 7065239552,
  "threshold": 10485760
 },
 "solr": {
  "description": "",
  "status": "UP",
  "solrStatus": "OK"
 },
 "redis": {
  "description": "",
  "status": "UP",
  "version": "2.8.21"
 },
 "db": {
  "description": "",
  "status": "UP",
  "authDataSource": {
   "description": "",
   "status": "UP",
   "database": "MySQL",
   "hello": "x"
  },
  "autodealerDataSource": {
   "description": "",
   "status": "UP",
   "database": "Microsoft SQL Server",
   "hello": "x"
  }
 }
}

关闭health检查的方法:

# application*.yml中
management:
  health:
    defaults:
      enabled: false

关闭后health检查结果:

{
 "description": "",
 "status": "UP",
 "application": {
  "description": "",
  "status": "UP"
 }
}

4. 如果有特定health检查的需求

关闭health检查后,如果需要某类health检查需求,则需要单独配置,配置方法如下:

management:
  health:
    defaults:
      enabled: false
    # 如下配置则打开db-health检查
    db:
      enabled: true

health检查结果如下:

{
 "description": "",
 "status": "UP",
 "db": {
  "description": "",
  "status": "UP",
  "authDataSource": {
   "description": "",
   "status": "UP",
   "database": "MySQL",
   "hello": "x"
  },
  "autodealerDataSource": {
   "description": "",
   "status": "UP",
   "database": "Microsoft SQL Server",
   "hello": "x"
  }
 }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用SpringBoot 工厂模式自动注入到Map

    使用SpringBoot 工厂模式自动注入到Map

    这篇文章主要介绍了使用SpringBoot 工厂模式自动注入到Map,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • nacos在liunx系统中启动成功浏览器却访问不了的解决方法

    nacos在liunx系统中启动成功浏览器却访问不了的解决方法

    在linux下搭建nacos,现在想要启动,访问nacos页面,访问不了,所以本文小编将给大家介绍nacos在liunx系统中启动成功,浏览器却访问不了?全面的解决办法,需要的朋友可以参考下
    2023-09-09
  • SpringBoot RESTful风格入门讲解

    SpringBoot RESTful风格入门讲解

    RESTful是一种web软件风格,它不是标准也不是协议,它不一定要采用,只是一种风格,它倡导的是一个资源定位(url)及资源操作的风格,这篇文章主要介绍了SpringBoot使用RESTful接口
    2022-11-11
  • 详解spring中使用Elasticsearch的代码实现

    详解spring中使用Elasticsearch的代码实现

    本篇文章主要介绍了详解spring中使用Elasticsearch的代码实现,具有一定的参考价值,有兴趣的可以了解一下
    2017-05-05
  • Tomcat内存溢出分析及解决方法

    Tomcat内存溢出分析及解决方法

    堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的,本文将详细介绍Tomcat内存溢出,需要了解更多的朋友可以参考下
    2012-11-11
  • Spring注解@Autowired和@Resource的区别详解

    Spring注解@Autowired和@Resource的区别详解

    这篇文章主要介绍了Spring注解@Autowired和@Resource的区别详解,@Autowired与@Resource都可以用来装配bean,都可以写在字段或setter方法上,@Resource是JDK提供的注解,默认按照名称进行装配,名称可通过name属性进行指定,需要的朋友可以参考下
    2023-12-12
  • 基于SpringBoot和Dify实现流式响应输出

    基于SpringBoot和Dify实现流式响应输出

    这篇文章主要为大家详细介绍了如何基于SpringBoot和Dify实现流式响应输出效果,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下
    2025-03-03
  • 关于Java的Character类详解

    关于Java的Character类详解

    这篇文章主要介绍了关于Java的Character类详解,Java中的Character类是一个包装类,用于封装一个基本数据类型char的值,它提供了一些静态方法来操作字符,需要的朋友可以参考下
    2023-05-05
  • 通过java.util.TreeMap源码加强红黑树的理解

    通过java.util.TreeMap源码加强红黑树的理解

    通过分析java.util.TreeMap源码来对经典问题红黑树加强理解和理清思路。
    2017-11-11
  • Java ThreadLocal 线程安全问题解决方案

    Java ThreadLocal 线程安全问题解决方案

    这篇文章主要介绍了Java ThreadLocal 线程安全问题解决方案的相关资料,需要的朋友可以参考下
    2016-09-09

最新评论