由于某些原因,我无法发布实际的代码;我会尽力清楚地解释我面临的问题。 在我的开发设置中,我运行 ansible play 来配置 3 个或更多节点。 另外,在本地我正在运行 Flask 服务器应用程序,它有几个端点,其中一个用于写入“公共文件”。
其中一项 ansible 任务被委托给 local_host。此任务在本地主机上运行多次(取决于目标主机的数量),并通过调用写入公共文件的端点来调用 Flask 服务器。这是我偶尔看到 500: 服务器内部错误的地方。
我确实理解从多个进程/线程写入公共文件可能会导致潜在的错误。我已经阅读过在此类场景中使用 sqlite3 DB 的情况。
这是开发设置,我需要了解 Flask 服务器有什么问题,在尝试解决问题之前我首先看到错误(可能没有 sqlite3)。
请注意,common_file 无论如何都不是一个大文件,并且要写入的数据(通过 ansible 任务)也很小
我确实理解从多个(...)线程写入公共文件可能会导致潜在的错误。
是的,写入由
open
创建的文件句柄不是线程安全的。
请注意,common_file 无论如何都不是一个大文件,并且 要写入的数据(通过ansible任务)也很小
问题是由一次多次写入文件引起的,而不是由写入内容的大小引起的。
我已经阅读过在此类场景中使用 sqlite3 DB 的情况。
这是解决这个问题的方法之一,但不是唯一的。其他替代方法是使用标准库中的
logging
,因为它是
日志记录模块旨在是线程安全的,无需任何特殊的 需要由客户完成的工作。它通过使用实现了这一点 螺纹锁;有一个锁可以序列化对模块的访问 共享数据,每个处理程序还创建一个锁来序列化访问 到其底层 I/O。
简单的例子,令
textsaver.py
内容为
import logging
from flask import Flask
logger = logging.getLogger('savedtexts')
logger.addHandler(logging.FileHandler('savedtexts.log'))
app = Flask(__name__)
@app.route("/<text>")
def textsaver(text):
logger.critical(text)
return text
然后
python -m flask --app textsaver run
将运行开发服务器,收集文本,例如参观后
savedtexts.log
的内容将是
hello
world