我试图编写一个在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')
上述"工作"除了我发送"关闭"信号,定期请求" /"没有回应,即使我们仍处于关闭和宽限期内#34; (上面代码中的20秒)。
似乎调用" time.sleep()"是同步的。
有没有人知道如何使这个"异步"?因此,应用程序将继续为请求提供服务,直到时间为#34; up"?
答案 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杀死。