Py学习  »  Python

Docker容器中的python,优雅地停止

Tigzy • 4 年前 • 1298 次点击  

我在一个 Windows Docker容器 ,我想 优雅地停下 是的。

脚本以这种方式在我的dockerfile中启动:

命令[“python.exe”,“/test.py”]

在Docker文档中说 发送SIGTERM信号 对主命令,所以我试着用这种方式捕捉它:

import signal
import time
import logging, sys

class GracefulKiller:
  kill_now = False
  def __init__(self):
    signal.signal(signal.SIGINT, self.exit_gracefully)
    signal.signal(signal.SIGTERM, self.exit_gracefully)

  def exit_gracefully(self,signum, frame):
    self.kill_now = True

if __name__ == '__main__':
  logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
  killer = GracefulKiller()
  while True:
    time.sleep(1)
    logging.info("doing something in a loop ...")
    if killer.kill_now:
      break

  logging.info("End of the program. I was killed gracefully :)")

理论上,信号应该由处理程序捕获,布尔值应该切换,循环应该退出并显示我最后的日志行。它没有,只是在信号发出的那一刻(或者2-3秒后)停止了整个过程。

C:\Users\Administrator\Documents\Projects\test>docker-compose up
Recreating test_1 ... done
Attaching to test_1
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
test_1  | INFO:root:doing something in a loop ...
Gracefully stopping... (press Ctrl+C again to force)
Stopping test_1   ... done

我的最后一行日志从未到达 是的。 有人知道怎么回事吗?这是python特有的问题,docker特有的还是windows特有的?

我也试着用Docker日志检查停止的容器,最后一个日志也不在这里。尝试在它之后添加睡眠,结果相同。

谢谢,

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/47027
 
1298 次点击  
文章 [ 1 ]  |  最新文章 4 年前
grapes
Reply   •   1 楼
grapes    5 年前

抓住 KeyboardInterrupt 就这样。

if __name__ == '__main__':
  logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
  try:
    while True:
      time.sleep(1)
      logging.info("doing something in a loop ...")
  except KeyboardInterrupt as ex:
    print('goodbye!')