小编Flo*_*anK的帖子

如何在 Django 请求处理程序线程中的 SIGTERM 上执行代码

我目前正在尝试了解 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)

python django sigterm

5
推荐指数
1
解决办法
1871
查看次数

标签 统计

django ×1

python ×1

sigterm ×1