背景

使用 docker stop 关闭容器时, 只有 init(pid 1)进程能收到中断信号, 如果容器的pid 1 进程是 sh 进程, 它不具备转发结束信号到它的子进程的能力, 所以我们真正的java程序得不到中断信号, 也就不能实现优雅关闭. 解决思路是: 让pid 1 进程具备转发终止信号, 或者将 java 程序配成 pid 1 进程.需要说明的是, docker stop 默认是等待10秒钟, 这个时间有点太短了, 可以加 -t 参数, 比如 -t 30 等待30秒钟.上面的 Dockerfile 的pid 1是一个 sh 命令,并不能实现优雅关闭, 需要再改进.

ENTRYPOINT/CMD 的几种写法, 会影响 pid 1 进程的产生:

写法1:

"shell" format 的 ENTRYPOINT/CMD, 不带方括号:
ENTRYPOINT top -b
#PID 1 是 /bin/sh -c shell  top -b
#另外有个 pid 7 是 top -b

写法2:

"shell" format 的 ENTRYPOINT/CMD, 不带方括号, 但这次ENTRYPOINT后紧跟了一个 exec :
ENTRYPOINT exec top -b
#PID 1 是 top -b

写法3:

"exec" form 的 ENTRYPOINT/CMD, 方括号括着, 每个部分都是json字符串.
ENTRYPOINT ["top","-b"]
pid 1 进程就是 top -b

所以推荐使用"exec" form的命令, 而不是 "shell" 形式的命令.

init 进程调整方案

方案1: 自行确保 pid 1 是我们的java程序.
上面的 Dockerfile 可以确保 java 程序作为 pid 1进程.

方案评价: 有时候不太容易将我们的主程序调整为 pid 1 进程, 另外虽然 docker 容器推荐是单进程, 但实际情形往往不是这么理想. 本方案仅仅适合单进程容器.

方案2: 适合于 Docker 1.13 以上.
Docker 1.13以上的docker run 命令新增了 --init 参数, 加了该参数后, docker 会启用 tini 作为 init (pid 1) 进程, 该 tini 进程能够将终止信号转发给其子进程, 同时能reap 子进程, 不会出现因孤儿进程导致的线程句柄无法回收情形.详见: https://github.com/krallin/tini

方案3(推荐): 在docker镜像中强制 tini 作为 init(pid 1) 进程, 该方案使用范围广, ENTRYPOINT 可以是任意sh脚本文件.

改造之前的 Dockerfile

ENTRYPOINT ["/docker-entrypoint.sh"]

改造后的 Dockerfile

# Add Tini
ENV TINI_VERSION v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tiniENTRYPOINT ["/usr/local/bin/tini", "--", "/docker-entrypoint.sh"]

tini 文档:https://github.com/krallin/tini。有关 docker run --init 参数的说明:http://stackoverflow.com/a/39593409/6309

Docker学习总结(50)——Docker 微服务优雅关闭相关推荐

  1. Docker容器及Spring Boot微服务应用

    2019独角兽企业重金招聘Python工程师标准>>> Docker容器及Spring Boot微服务应用 1 什么是Docker 1.1 Docker的出现 问题一:项目实施环境复 ...

  2. 【Spring Cloud 基础设施搭建系列】Spring Cloud Demo项目 使用Docker Compose编排Spring Cloud微服务

    文章目录 Docker Compose快速人门 入门示例 使用Docker Comose编排Spring Cloud微服务 使用Maven插件读取Dockerfile进行构建 使用Maven插件构建D ...

  3. 『高级篇』docker容器来说什么是微服务(三)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『高级篇』docker容器来说什么是微服务(三) 上一节说了单体架构,单体架构也无法适应我们的服务,来说说微服务,看能否解决单 ...

  4. Spring Boot与Docker(一):微服务架构和容器化概述

    本文讲的是Spring Boot与Docker(一):微服务架构和容器化概述,[编者的话]本篇是<使用Spring Boot和Docker构建微服务架构>系列四部曲的第一篇,本篇将会对我们 ...

  5. 学习笔记:SpringCloud 微服务技术栈_实用篇①_基础知识

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 前言 学习视频链接 SpringCloud + RabbitMQ + Docker + Redis + 搜 ...

  6. Docker学习二:Docker镜像与容器

    前言 本次学习来自于datawhale组队学习: 教程地址为: https://github.com/datawhalechina/team-learning-program/tree/master/ ...

  7. 微服务优雅上下线的实践方法

    导语 本文介绍了微服务优雅上下线的实践方法及原理,包括适用于 Spring 应用的优雅上下线逻辑和服务预热,以及使用 Docker 实现无损下线的 Demo.同时,本文还总结了优雅上下线的价值和挑战. ...

  8. Docker学习五:Docker 数据管理

    前言 本次学习来自于datawhale组队学习: 教程地址为: https://github.com/datawhalechina/team-learning-program/tree/master/ ...

  9. Docker学习四:Docker 网络

    前言 本次学习来自于datawhale组队学习: 教程地址为: https://github.com/datawhalechina/team-learning-program/tree/master/ ...

最新文章

  1. html中radio、checkbox选中状态研究(静下心来看,静下心来总结)
  2. 让VBCommenter支持自定义用户名
  3. EF-CodeFirst-域模型配置
  4. HTML转义字符大全
  5. springboot统一异常处理类及注解参数为数组的写法
  6. Zookeeper源码分析(二) ----- zookeeper日志
  7. android项目编译命令行,命令行编译Android项目
  8. 汇编比较两个数大小_计算机是怎样跑起来的 -- 体验一次汇编过程
  9. java mail 不用密码_iPhone 无需越狱,简单给 App 加密码锁
  10. Java基础-IO流
  11. yum php mysql apache,CentOS yum 安装 Apache + PHP + MySQL
  12. rk3399 io工具的使用示例
  13. 51 Nod 1005 大数加法【Java大数乱搞,python大数乱搞】
  14. XGBoost和LightGB
  15. java字符串替换字符串_java string 字符串替换
  16. 蛋白质组学与转录组学联合分析
  17. 重庆—java互联网架构软件工程师学习记录—Day11(API 1)
  18. mysql raw_rails - 直接执行raw sql. 查询mysql的基本数据
  19. wap实现手机充话费
  20. Leetcode 1125:最小的必要团队

热门文章

  1. python多线程编程技术主要应用_python多线程,多进程编程。
  2. 管理后台--1.创建分类
  3. 原生html开发环境,推荐HTML5/Javascript的开发环境?
  4. gif透明背景动画_图片的不同格式:JPG、PNG、GIF都有什么区别?
  5. 计算机类有电子商务类,电子商务类专业有哪些-电子商务类专业名单汇总
  6. oracle11g 端口,navicate 连接 oracle11g精简版监听不到端口和用户密码错误问题
  7. html获取节点属性,JS操作属性节点(非常详细)
  8. linux将屏幕输出内容转储到文件,Linux实时将所有输出重定向到文件
  9. mysql三高讲解(一):1.1 客户端怎样连接mysql数据库
  10. C++安全方向(三):3.2 单项散列函数的应用场景