如何在Flash中运行后台定时器

2024-05-15 22:25:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图编写一个Flask应用程序,它在Kubernetes中运行时行为正常,尤其是在graceful shutdown中。在

因此,我需要有代码:

  • 接收停机信号
  • 启动“关机定时器”
  • 继续正常服务请求,直到时间“结束”
  • 然后自己关掉

到目前为止,我得到的是:

from flask import Flask, abort
import signal
import time
app = Flask(__name__)
shuttingDown = False

def exit_gracefully(self, signum):
    app.logger.error('Received shutdown signal. Exiting gracefully')
    global shuttingDown
    shuttingDown = True
    # TODO: wait for some time here to ensure we are not receiving any more
    # traffic
    time.sleep(20)
    exit(0)

signal.signal(signal.SIGTERM, exit_gracefully)

@app.route("/")
def hello():
        return "Hello World!"

@app.route("/_status/liveness")
def liveness():
        return "I am alive"

@app.route("/_status/readiness")
def readiness():
        if not shuttingDown:
            return "I am ready"
        else:
            abort(500, 'not ready anymore')

以上“工作”除了在我发出“关机”信号后,正常的请求“/”都不会得到响应,即使我们仍在关机“宽限期”(以上代码中为20秒)内。在

似乎是为了时间。睡觉()”是同步的。在

有人知道有什么方法可以让这个“异步”吗?让应用程序继续服务请求直到时间“结束”?在


Tags: importapp应用程序flasksignalreturntimedef
2条回答

这适用于内部服务器。需要注意的是,有一个/\u shutdown URL可以关闭服务器,这对恶意关闭是开放的。如果这不是您想要的,那么删除requests.post()并取消{}的注释。当然还要删除@app.route("/_shutdown")和函数。在

from flask import Flask, abort, request
import signal
import threading
import time
import os
import requests
app = Flask(__name__)
shuttingDown = False


def exit_call():
    time.sleep(20)
    requests.post("http://localhost:5420/_shutdown")
    # os._exit(0)


def exit_gracefully(self, signum):
    app.logger.error('Received shutdown signal. Exiting gracefully')
    global shuttingDown
    shuttingDown = True
    # TODO: wait for some time here to ensure we are not receiving any more
    # traffic
    _et = threading.Thread(target=exit_call)
    _et.daemon = True
    _et.start()


signal.signal(signal.SIGTERM, exit_gracefully)


@app.route("/")
def hello():
        return "Hello World!"


@app.route("/_status/liveness")
def liveness():
        return "I am alive"


@app.route("/_shutdown", methods=["POST"])
def shutdown():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        return "Not a werkzeug server"
    func()
    return "shutdown"


@app.route("/_status/readiness")
def readiness():
        if not shuttingDown:
            return "I am ready"
        else:
            abort(500, 'not ready anymore')


app.run(port=5420)

您可能正在使用内置Flask开发服务器。Flask和Django中的此类内置开发服务器,或标准库中基于web服务器或WSGI服务器的任何东西都不适用于生产系统,并且通常不能正确处理信号关闭。在

因此,您应该真正使用适当的生产级WSGI服务器,例如Apache/mod_WSGI(mod_WSGI-express)、gunicorn或uWSGI。这些都能正确地处理信号,并且开发服务器不会遇到这样的问题:开发服务器会忽略导致容器关闭延迟的信号,当关闭超时发生时,它最终会被Kubernetes杀死。在

相关问题 更多 >