Docker 部署Spring boot 项目如何优雅的关闭(Eureka下线)
问题描述:
Docker 直接停止镜像,spirngCloud服务直接停止,并未正常从注册中心下线。
问题原因:
- 使用 docker stop 关闭容器时, 只有 init(pid 1)进程能收到中断信号, 如果容器的pid 1 进程是 sh 进程, 它不具备转发结束信号到它的子进程的能力, 所以我们真正的java程序得不到中断信号, 也就不能实现优雅关闭
- 关闭动作并未传递到我们自己运行的进程中。
解决方案:
- 通过运行exec命令,它将代替shell进程把SIGTERM传播到应用线程
- ENTRYPOINT [ "sh", "-c", "exec java -jar /apps/app.jar"]
Spring 官方资料 :https://spring.io/guides/topicals/spring-boot-docker
具体如何修改:
- docker-maven-plugin 插件配置修改
- 原先:
<entryPoint>["java","-jar","/${project.build.finalName}.jar"]</entryPoint>
- 修改为:
<entryPoint>["sh","-c","execjava-jar/${project.build.finalName}.jar"]</entryPoint>
实验测试:
运行容器 run
- 服务正常注册,注册中心接口 返回状态码 204
停止容器 stop
- 触发spring容器注销事件, 注册中心接口返回状态码 204 ,服务在注册中心状态为 DOWN
重要说明:
Docker Kill 命令不支持!
Kill 容器之间杀死,可以看做是宿主机直接杀死了一个进程,触发不了,注销事件。