当他们尝试访问相同文件时,如何防止Gunicorn工作人员崩溃

时间:2018-11-28 15:12:44

标签: python multithreading flask gunicorn

我的Flask应用程序将请求记录在单独的json文件中,因为它们很大,只会使普通的文本日志(例如app.logger.info(".."))混乱。它将最近的 n 个请求保留在某个文件夹中。

更准确地说,一个函数会遍历所有json文件,并且当存在多个 n 时,它会一次删除一个,然后添加新请求:

logfiles = sorted(glob.glob("*.json"))

while len(logfiles) >= n:
    os.remove(logfiles.pop(0))

我将该应用程序与gunicorn服务器一起使用,并注意到,对于相同的请求,它有时会崩溃,有时会成功。发生崩溃后会显示以下信息:

[18935] [INFO] Handling signal: int
[18935] [INFO] Shutting down: Master

我猜想有两个枪手工人正在同时访问日志文件夹并尝试删除相同的文件。因此,这两个文件之一将崩溃,因为文件已消失。我已经知道(=听说过)使用多个线程进行编程时的这种类型的问题,但是到目前为止,我从来没有自己解决过这个问题。

我想我将不得不锁定文件夹并创建一个试图向该文件夹添加/删除文件的工作人员队列?最好的方法是什么?我应该使用threading之类的可用模块还是 Queue?它们会与Flask和Gunicorn一起平稳运行吗?还是应该实现自己的队列?

PS:这是How to log large requests as files?

的后续问题

1 个答案:

答案 0 :(得分:1)

当python运行时尝试访问不存在的文件时,它将引发异常。您的代码没有处理该异常的方法,结果,gunicorn线程引发了中断信号并崩溃。处理此问题的最基本方法是使用try block封装尝试访问/删除文件的代码:

try:
    # Code that tries to access the file
    while len(logfiles) >= n:
        os.remove(logfiles.pop(0))
except:
    # Code that you want to execute after the operation fails 

这适用于删除页面,但是如果在尝试写入文件时遇到其他错误,您可能还希望使用filelock之类的东西。