我目前正在尝试了解 Django 中收到 SIGTERM 时的信号处理。
我有一个可能需要长时间运行的请求的应用程序,在 Docker 容器中运行。当Docker想要停止一个容器时,它首先发送一个SIGTERM信号,等待一段时间,然后发送一个SIGKILL。通常,在 SIGTERM 上,您停止接收新请求,并希望当前正在运行的请求在 Docker 决定发送 SIGKILL 之前完成。但是,在我的应用程序中,我想保存已尝试过的请求,并发现这比立即完成请求更重要。因此,我更喜欢在 SIGTERM 上关闭当前请求,以便我可以优雅地结束它们(并保存它们的状态),而不是等待 SIGKILL。
我的理论是,您可以为 SIGTERM 注册一个信号监听器,该监听器执行sys.exit(),以便SystemExit引发异常。然后我想在我的请求处理程序中捕获该异常,并保存我的状态。作为第一个实验,我为 Django 开发服务器创建了一个模拟项目。我在函数中注册了信号Appconfig.ready():
import signal
import sys
from django.apps import AppConfig
import logging
logger = logging.getLogger(__name__)
def signal_handler(signal_num, frame):
sys.exit()
class TesterConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'tester'
def ready(self):
logger.info('starting ready')
signal.signal(signal.SIGTERM, signal_handler)
Run Code Online (Sandbox Code Playgroud)
并创建了一个捕获异常和 BaseException 的请求处理程序:
import logging
import sys
import time
from django.http import HttpResponse
def handler(request):
try:
logger.info('start')
while True: …Run Code Online (Sandbox Code Playgroud)