Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

4.3. 容器中如何优雅关闭 Springboot

容器与进程模式并没有什么区别,我们给容器发送终止信号,容器会转发给 Springboot。

理论归理论,我们还是需要亲自实践,这样才能理解更深刻。

准备实验环境和素材,下面是 docker-compose.yaml 编排文件

		
version: '3.9'
  
services:
  spring:
    image: openjdk:latest
    container_name: spring
    restart: always
    hostname: www.netkiller.cn
    environment:
      TZ: Asia/Shanghai
      JAVA_OPTS: -Xms256m -Xmx512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
    ports:
      - 8099:8080
    volumes:
      - ./test-0.0.1-SNAPSHOT.jar:/app/test-0.0.1-SNAPSHOT.jar
    entrypoint: java -jar /app/test-0.0.1-SNAPSHOT.jar
    command:
      --spring.profiles.active=dev
      --server.port=8080
		
		

实验步骤

运行容器

		
[root@localhost netkiller.cn]# docker-compose up -d
Starting spring ... done
		
		

观察容器日志

		
[root@localhost netkiller.cn]# docker-compose logs -f
spring    | Starting...
spring    | 
spring    |   .   ____          _            __ _ _
spring    |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
spring    | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
spring    |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
spring    |   '  |____| .__|_| |_|_| |_\__, | / / / /
spring    |  =========|_|==============|___/=/_/_/_/
spring    |  :: Spring Boot ::                (v2.5.3)
spring    | 
spring    | 2021-07-29 11:29:34.556  INFO 1 --- [           main] cn.netkiller.Application                 : Starting Application v0.0.1-SNAPSHOT using Java 16.0.2 on www.netkiller.cn with PID 1 (/app/test-0.0.1-SNAPSHOT.jar started by root in /)
spring    | 2021-07-29 11:29:34.559  INFO 1 --- [           main] cn.netkiller.Application                 : The following profiles are active: dev
spring    | 2021-07-29 11:29:35.903  WARN 1 --- [           main] io.undertow.websockets.jsr               : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
spring    | 2021-07-29 11:29:35.921  INFO 1 --- [           main] io.undertow.servlet                      : Initializing Spring embedded WebApplicationContext
spring    | 2021-07-29 11:29:35.921  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1274 ms
spring    | 2021-07-29 11:29:36.411  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint(s) beneath base path '/actuator'
spring    | 2021-07-29 11:29:36.437  INFO 1 --- [           main] io.undertow                              : starting server: Undertow - 2.2.9.Final
spring    | 2021-07-29 11:29:36.444  INFO 1 --- [           main] org.xnio                                 : XNIO version 3.8.4.Final
spring    | 2021-07-29 11:29:36.451  INFO 1 --- [           main] org.xnio.nio                             : XNIO NIO Implementation Version 3.8.4.Final
spring    | 2021-07-29 11:29:36.511  INFO 1 --- [           main] org.jboss.threads                        : JBoss Threads version 3.1.0.Final
spring    | 2021-07-29 11:29:36.547  INFO 1 --- [           main] o.s.b.w.e.undertow.UndertowWebServer     : Undertow started on port(s) 8080 (http)
spring    | 2021-07-29 11:29:36.560  INFO 1 --- [           main] cn.netkiller.Application                 : Started Application in 2.48 seconds (JVM running for 2.923)
		
		

停止容器

		
[root@localhost netkiller.cn]# docker ps | grep spring
8901384d1973   openjdk:latest                "java -jar /app/test…"   3 minutes ago   Up About a minute   0.0.0.0:8099->8080/tcp, :::8099->8080/tcp                                              spring
[root@localhost netkiller.cn]# docker stop spring
spring
[root@localhost netkiller.cn]# docker ps | grep spring		
		
		

在观察日志

		
spring    | 2021-07-29 11:31:31.807  INFO 1 --- [ionShutdownHook] io.undertow                              : stopping server: Undertow - 2.2.9.Final
spring    | ==============================
spring    | Destroying Spring
spring    | ==============================
spring exited with code 143		
		
		

现在可以看到 Springboot 是正常退出的

下面我们再做一个实验 docker kill

		
[root@localhost netkiller.cn]# docker-compose start
Starting spring ... done

[root@localhost netkiller.cn]# docker-compose logs -f
		
[root@localhost netkiller.cn]# docker kill spring
spring		
		
		

此时再观察日志,只输出了一行。

		
spring exited with code 137
		
		

结论,docker kill = kill -9

现在你应该明白什么时候该使用什么命令终止程序了吧,同时我们在写程序的时候,也应该将程序的运行状态反应出来,在我们停止程序运行的时候,可以去观察进程的状态,而不是半天没有反应,只能怀疑进程死了,必须执行B计划(kill -9)这会造成很多数据丢失的问题。