• 关于springboot的优雅停机和健康检查配置(用于k8s服务重启)


    优雅停机

    所谓的优雅停机指的是(一方面可以在停机的时候通过背板挡住外来正在发送的请求,另一方面已经接受的请求能够很好的执行完接下来的业务)。服务在关闭的时候,不能通过强制kill进程的方式进行停止,这样的话,对于有些未处理完成的业务会造成数据的补偿.

    一. 优雅停机

    1. 如果是springboot2.3版本之前可以通引入如下jar

    <dependency>
        <groupId>com.github.timpeeters</groupId>
        <artifactId>spring-boot-graceful-shutdown</artifactId>
        <version>X.X.X</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    版本可参考:
    在这里插入图片描述
    在这里插入图片描述
    就可以实现优雅停机了

    2、如果springboot是2.3版本之后,则可以直接在application.yml做如下配置即可

    server:
      # 开启优雅关闭,默认:IMMEDIATE,立即关闭
      shutdown: graceful
    
    spring:
      lifecycle:
        # 配置优雅关闭宽限时间,即项目在30s都没处理完,则进行强制关闭
        timeout-per-shutdown-phase: 30s
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    二. 健康检查配置

    添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4

    配置application.yml,如下

      management:
    #  也可指定ip和端口进行访问
    #  server:
    #    address: 127.0.0.1
    #    port: 5000
      # 开启shutdown endpoint
      endpoint:
    #    需要关机就要进行配置默认都是flase
        shutdown:
          enabled: true
        health:
          enabled: true
      endpoints:
        web:
          base-path: /actuator  #访问http://127.0.0.1:8083/actuator/health
          exposure:
            # 暴露shutdown health(访问http://127.0.0.1:8083/actuator/health进行健康检测
            # 访问http://127.0.0.1:8083/actuator/shutdown进行优雅停机)
            include: shutdown,health
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    访问http://127.0.0.1:8083/actuator/health进行健康检测

    http://127.0.0.1:8083/actuator/shutdown进行优雅停机

    另外,其他端点的路径如下表格,注意,前面需要添加/actuator根路径,如下

    在这里插入图片描述

    三. springboot在docker容器中如何进行优雅关闭

    如果在Dockerfile做如下配置

    ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
    
    • 1

    是没法实现优雅关闭的效果。其原因是使用 docker stop 关闭容器时, 只有 init(pid 1)进程能收到中断信号, 如果容器的pid 1 进程是 sh 进程, 它不具备转发结束信号到它的子进程的能力, 所以我们真正的java程序得不到中断信号, 也就不能实现优雅关闭. 解决思路是: 让pid 1 进程具备转发终止信号, 或者将 java 程序配成 pid 1 进程.
    因此只需对Dockerfile做如下改造就行

    ENTRYPOINT [ "sh", "-c", "exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
    
    • 1

    其实就是在java前边加上exec即可。其实现机理可以参考如下链接
    https://spring.io/guides/topicals/spring-boot-docker

    在k8s中如何进行优雅关闭

    1、配置preStop Hook钩子

    preStop Hook 是一个发送到 Pod 中的容器特殊命令或 Http 请求。如果您的应用程序在接收 SIGTERM 时没有正常关闭,您可以使用 preStop Hook 来触发正常关闭。接收 SIGTERM 时大多数程序都会正常关闭,但如果您使用的是第三方代码或管理的系统无法控制,则 preStop Hook 是在不修改应用程序的情况下触发正常关闭的好方法。
    2、适当延长terminationGracePeriodSeconds时间

    其配置参考如下

    apiVersion: v1 
    kind: Pod 
    metadata:
      name: demopod
    spec:
      containers:
      - image: springboot-demo:v1.10
        name: demo-container
        ports:
        - containerPort: 8080
        lifecycle:
          preStop:
            exec:
              command: ["curl", "-XPOST", "127.0.0.1:8083/actuator/shutdown"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    总结

    优雅关闭正常都是会配置一定的处理时间,超过该时间没处理完,就会进行强杀。因此对于核心业务,我们还得考虑万一进行强杀时,还要考虑是否需要对业务进行补偿操作

  • 相关阅读:
    C语言动态内存空间分配
    小型企业团队的理想项目管理软件解决方案
    java8---1、为什么要用lambda表达式?
    MySQL如何快速获取binlog的开始时间和结束时间
    Tempo数据分析平台,助力企业高效完成数据预处理工作
    通过git命令查询某个用户提交信息
    node.js提取excel中的信息填充到word文件,批量生成合同
    读入分组后写成多个文件
    IgH Master环境搭建
    07-服务管理-02-yum常用命令和yum源
  • 原文地址:https://blog.csdn.net/qq_28340701/article/details/126371263