网站首页 > 教程文章 正文
服务如何响应停机信号
在java中我们可以直接利用通过Runtime来注册一个停机的钩子函数
Runtime.getRuntime().addShutdownHook(new Thread(
new Runnable() {
@Override
public void run() {
// 实现自己的停机逻辑,例如:关闭资源、等待请求处理完成等....
System.out.println("我被kill了");
}
}
));
在SpringBoot环境下,默认已经给我们注册了这个钩子:
?
org.springframework.boot.SpringApplication#refreshContext
在这个钩子函数中,Spring容器会去执行自己的doClose方法关闭容器
跟踪这个doClose方法会发现,关闭容器的第一步会发送一个ContextClosedEvent事件
因此在SpringBoot环境下我们只需要实现一个事件监听器就可以捕捉到应用的停机信号,实现优雅停机
@Component
public class MyShutdownHook implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
// 优雅停机。。。
}
}
利用SpringBootActuator实现探针
在上篇文章中,咱们提到了需要配置K8s的探针,配置如下:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
# 在containers下添加两个指针
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
# pod启动后延迟60s探测
initialDelaySeconds: 45
# 每30s测一次
periodSeconds: 10
# 每次探测最大超时时间3s
timeoutSeconds: 3
# 连续6次探测失败则重启pod
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 45
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
其中需要实现两个接口:
- /actuator/health/liveness,用于存活探测
- /actuator/health/liveness,用于就绪探测
如何实现这两个接口呢?
我们只需要接入spring boot actuator,再进行一些简单配置即可
第一步:引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
第二步:添加配置
endpoints:
web:
exposure:
include: health
endpoint:
health:
group:
liveness:
include:
- ping
readiness:
include:
- "*"
show-details: always
endpoints.web.exposure.include代表服务需要暴露哪些actuator的端点,咱们这里只讨论健康检查,因此只打开health端点
在上面的配置中通过endpoint.health.group将health端点分为两组:liveness、readiness,对应咱们在探针中配置的livenessProbe跟readinessProbe
在liveness探测中,我只配置了ping,其作用相当于访问下面这样的一个接口:
@RestController("/health")
public class HealthCheck {
@GetMapping
public String check(){
return "ok";
}
}
对于readiness探测,配置了*,代表要对所有的组件进行检查
我们可以通过访问:localhost:8080/actuator/health/readiness来确认目前检查了哪些组件,其返回格式如下:
{
"status": "DOWN",
"components": {
"custom": {
"status": "DOWN",
"details": {
"message": "My application is healthy!"
}
},
"db": {
"status": "UP",
"details": {
"database": "MySQL",
"validationQuery": "isValid()"
}
},
"mongo": {
"status": "DOWN",
"details": {
"error": "org.springframework.data.mongodb.UncategorizedMongoDbException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1}; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential"
}
},
"ping": {
"status": "UP"
}
}
}
通过这个接口的访问信息,咱们也可以发现目前我这个服务的mongoDB是无法连接的,另外有一个定制的端点custom是挂掉的。需要注意的是,只要有一个端点检查是down的状态,整个检查就是不通过的。
定制一个检查的端点也非常简单,如下:
// 需要在endpoint.health.group.readiness.include中添加这个custom端点
@Component("custom")
public class CustomHealthCheck extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
if (检查不通过) {
builder.down().withDetail("reason", "我挂掉了").withException(new RuntimeException("测试异常"));
} else {
builder.up();
}
}
}
踩过的坑
- 添加liveness跟readiness探针后, healthcheck会根据配置判断组件的状态, 如果组件状态异常,会导致pod重启, 在特殊场景下, 组件异常并不需要重启, 需要使用方自行判断。可以通过http://localhost:8080/actuator/health/readiness跟http://localhost:8080/actuator/health/liveness确认当前应用配置了哪些组件举例场景:redis挂掉, 但是在服务中, redis缓存允许穿透或者异常, redis挂掉不应该重启机器, 这个在healthcheck中,redis状态异常不应该触发liveness和readness失败
- initialDelaySeconds的值应该根据应用启动时间进行合理设置,如果设置过短,会导致pod反复被kill无法正常启动
- 整个优雅启停的上线应该分为两步
- 代码改造,接入SpringBootActuator
- deployment文件更新
- 推荐的做法是,代码改造完成后先上线,上线之后选择某一个pod测试服务的liveness跟readiness探测接口,确认探测接口的调用对服务没有影响后再apply改动过的deployment文件。笔者在实际落地的时候就碰到过某些测试环境没问题,上线之后只要调用redis的探测,服务立马宕机,之后就进入不断重启、宕机的死循环,并且,回滚的时候需要同时操作deployment文件跟回滚代码,那种感觉别提有多酸爽
猜你喜欢
- 2025-01-20 精通Spring Boot 3 : 11. Spring Boot 监控工具 (1)
- 2025-01-20 「Spring Boot」 Actuator Endpoint
- 2025-01-20 深入了解Spring Boot Actuator健康检查:让你的应用程序永不掉线
- 2025-01-20 SpringBoot应用监控解析:Actuator实现原理
- 2025-01-20 如何在Spring Boot中整合Spring Boot Actuator进行服务应用监控?
- 2025-01-20 Spring Boot进阶-SpringBoot管理工具Actuator介绍
- 2025-01-20 Spring boot——Actuator 详解
- 2025-01-20 非常简单 | 使用Actuator 从零开始搭建Spring Boot 应用监控系统
- 2025-01-20 突破Spring Boot Actuator面试:25道题及答案
- 2025-01-20 搭建应用的“时间管理局”- Spring Boot Actuator (一)
- 最近发表
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)