自从接触了 Docker 之后,在服务器上跑的 Python 程序,我基本上都是使用 Docker 进行部署,利用 Docker 镜像可以规避一些环境差异带来的坑。
Docker 可以通过启动、停止容器来控制程序的运行状态。那停止容器的时候,里面运行程序是如何停下来的呢?程序有没有正常退出呢?可以通过一个 Demo 程序来实验一下。
下面是一个简易版的程序:
本地构建镜像,然后启动一个容器跑起来,稍等一会,然后停止容器。可以看到容器的 Exit code 并不为 0,也就是说程序并没有正常退出。
根据 Docker 官方文档 的说明,停止容器时,会先给容器发一个 SIGTERM
信号,等待超时后,会再给容器发一个 SIGKILL
信号,强行停止程序。
前面的程序并没有在接收 SIGTERM
信号时,并没有及时停止,最终被强制杀掉。为了保证程序能够正常收尾退出,需要处理 SIGTERM
信号,利用 Python 中的 signal 模块可以轻松实现。
具体实现很简单,添加 SIGTERM
信号的回调,然后在循环的时候判断下退出条件就好了。
此时重新走一遍流程,构建镜像、启动、停止容器,再查看一下状态。此时程序 Exit code 为 0,说明它正常退出。
查看日志,可以看到程序循环结束之后,后面的收尾工作也执行了。
实际使用中,可以在接到 SIGTERM
信号之后,把内存数据进行持久化,防止数据、状态丢失;
如果不处理的话,可能会导致资源不能正常释放,数据丢失等状况。
文中代码预览图生成工具 Carbon