SpringCloud健康检查的陷阱
健康检查
基于Spring Boot Actuator的健康检查是Spring Cloud微服务的必备组件,用来确保我们的服务是否可用。
引入 Spring Boot Actuator后,通过http://ip:port/health ,可以看到 HealthEndPoint 给我们提供默认的监控结果,包含磁盘检测和数据库检测。如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
{
"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。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
{
"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"
}
}
|
由于邮件发送不是核心功能,可以把非核心组件从健康检查中排除,避免造成整个服务不可用。
通过如下配置关闭邮箱健康检查。
1
|
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检查结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
{
"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检查的方法:
1
2
3
4
5
|
# application*.yml中
management:
health:
defaults:
enabled: false
|
关闭后health检查结果:
1
2
3
4
5
6
7
8
|
{
"description" : "" ,
"status" : "UP" ,
"application" : {
"description" : "" ,
"status" : "UP"
}
}
|
4. 如果有特定health检查的需求
关闭health检查后,如果需要某类health检查需求,则需要单独配置,配置方法如下:
1
2
3
4
5
6
7
|
management:
health:
defaults:
enabled: false
# 如下配置则打开db-health检查
db:
enabled: true
|
health检查结果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
{
"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"
}
}
}
|
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/j16421881/article/details/82717372