如何在Flask

时间:2017-09-28 08:15:05

标签: python multithreading flask kubernetes

我试图编写一个在Flask中投放时行为正确的Kubernetes应用,特别是涉及graceful shutdown时。

因此,我需要有代码:

  • 收到关机信号
  • 启动"关闭计时器"
  • 继续按正常方式提出请求,直到#34; up"
  • 为止
  • 然后自行关闭

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

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')

上述"工作"除了我发送"关闭"信号,定期请求" /"没有回应,即使我们仍处于关闭和宽限期内#34; (上面代码中的20秒)。

似乎调用" time.sleep()"是同步的。

有没有人知道如何使这个"异步"?因此,应用程序将继续为请求提供服务,直到时间为#34; up"?

2 个答案:

答案 0 :(得分:1)

这适用于内部服务器。需要注意的是,有一个/ _shutdown URL会关闭服务器,这可能会导致恶意关闭。如果这不是您想要的,请删除const normalizeCid = (value) => { const noLeadingZeros = value.toString().replace(/\b(0+)/, ''); return padLeft(noLeadingZeros, 8); }; const padLeft = (num, len) => ( // num is already a string now len > num.length ? '0'.repeat(len - num.toString().length) + num : num ); 并取消注释requests.post()。当然还要删除os._exit()和函数。

@app.route("/_shutdown")

答案 1 :(得分:1)

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

因此,您应该使用适当的生产级WSGI服务器,例如Apache / mod_wsgi(mod_wsgi-express),gunicorn或uWSGI。这些都可以正确处理信号,你没有开发服务器的问题,他们忽略导致容器关闭延迟的信号,最终在关机超时发生时被Kubernetes杀死。