How to gracefully close the springboot project in the docker container

01 Preface

1 what is elegant closure

In my opinion, the so-called elegant shutdown is to reserve some time for you to deal with the aftermath when the system is shut down

2 when do I need to close gracefully

Do all projects need to be closed gracefully? That's not necessarily. After all, the so-called elegant closing means that the closing is slow. Therefore, the elegant closing of the project depends on the core degree of the project. In other words, it depends on whether the data processed by the project is core data. In fact, the ultimate essence of the project is the processing of data.

3 how to achieve elegant closing

The general method is realized by the process receiving the signal variable sent by the system. For what is the signal variable, please refer to the following link

https://www.cnblogs.com/liuhouhou/p/5400540.html

02 how to configure graceful shutdown in springboot project

1 if it is springboot2 Before version 3, you can import the following jar

<dependency>
    <groupId>com.github.timpeeters</groupId>
    <artifactId>spring-boot-graceful-shutdown</artifactId>
    <version>X.X.X</version>
</dependency>

By introducing this jar, and in the application. Jar of the project YML file configuration

graceful:
  shutdown:
    enabled: true

Elegant closure in just two steps. When the project is closed, observe the log and find the following output

Spring boot graceful shutdown currently supports the following spring boot versions

Implementation process

For more detailed tutorials, please refer to the following links

https://github.com/timpeeters/spring-boot-graceful-shutdown

2springboot2. After version 3, it can be used in application YML can be configured as follows

server:
  # Open and close gracefully. Default: IMMEDIATE. Close immediately
  shutdown: graceful

spring:
  lifecycle:
    # Configure grace closing grace time, that is, if the item is not processed in 30s, it will be forced to close
    timeout-per-shutdown-phase: 30s

Its closing effect is as follows

2021-01-15 10:52:04.063  INFO 39004 --- [extShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2021-01-15 10:52:04.138  INFO 39004 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_HELLO-LOCAL/hello-local:172.17.45.115:8080 - registration status: 204
2021-01-15 10:52:04.605  INFO 39004 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
c.netflix.discovery.TimedSupervisorTask : task supervisor shutting down, can't accept the task

03 how to close gracefully in docker container

If you configure the Dockerfile as follows

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

It is impossible to achieve the effect of elegant closing. The reason is that when using docker stop to close the container, only init(pid 1) process can receive the interrupt signal. If the pid 1 process of the container is sh process, it does not have the ability to forward the end signal to its sub process. Therefore, our real java program can not get the interrupt signal and can not close gracefully The solution is: let the pid 1 process have the ability to forward the termination signal, or configure the java program into the pid 1 process. Therefore, you only need to make the following modifications to the Dockerfile

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

In fact, you can add exec in front of java. The implementation mechanism can refer to the following links

https://spring.io/guides/topicals/spring-boot-docker

04 how to close gracefully in k8s

1. Configure preStop Hook

preStop Hook is a container special command or Http request sent to Pod. If your application does not shut down normally when receiving SIGTERM, you can use preStop Hook to trigger normal shutdown. Most programs will shut down normally when receiving SIGTERM, but if you are using third-party code or the managed system cannot control it, preStop Hook is a good way to trigger normal shutdown without modifying the application.

2 extend the termination graceperiodseconds time appropriately

The meaning of termination grace period seconds can be seen directly as follows

The configuration reference is as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: dev
  name: hello
  labels:
    app: hello
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
    spec:
      imagePullSecrets:
      - name: default-secret
      containers:
      - name: hello
        image: {{images}}
        ports:
          - containerPort: 8080
        lifecycle:
          preStop:
            httpGet:
              port: 8080
              path: The action you want to perform when closing
      terminationGracePeriodSeconds: 60

05 summary

Graceful shutdown is normally configured with a certain processing time. If the processing is not completed after that time, forced killing will be carried out. Therefore, for the core business, we have to consider whether to compensate the business in case of forced killing

Added by gersh on Thu, 06 Jan 2022 12:44:59 +0200