首页 > 解决方案 > 间歇性 Firestore 超时锁定整个客户端

问题描述

尽管有 30 多年的编程经验,但还是第一次在这里发帖。关于firestore python客户端库的一些事情让我发疯了。

应用程序正在为流量提供服务并使用 Firestore 进行持久化。Gunicorn 奔跑@云奔跑。Firestore 文档 .get 和 .set 操作有时会超时。客户端库的公开 API 无法控制超时。

我包装在sync_to_async() 中的所有firestore 阻塞操作。

所有 .get() 操作也都用 asyncio.wait_for(...) 包装,并带有超时,并且有效。

对于 .set() 操作,似乎不可能强制执行任何类型的超时,因为公共 api 没有任何方法,并且 wait_for(...) 不会中断包装的阻塞代码。因此,当这些失败时,客户端 http 请求会被后端服务前面运行的 ESP 终止。不理想,因为我可以在后端更好地处理它(例如重试或安全回退)。

我非常感谢帮助我弄清楚如何对 firestore 文档 set() 操作强制超时。该应用程序面向用户并接受我认为是 2 分钟左右的默认超时,这是不切实际的。我宁愿报告失败,或者重试。

此外,我观察到每隔几天,当 Firestore 操作因这样的超时而失败,并且受影响的请求被前面运行的 nginx ESP 超时时,firestore 客户端的状态会以某种方式损坏,从而阻止任何后续写入成为可能。有帮助的是重新创建 firestore 客户端对象。

由于无法控制超时或获得本机异步支持,我即将切换到不同的数据库项目。

任何建议将不胜感激。

示例代码:

try:
    document = await asyncio.wait_for(db_get_fs(collection_name, id, trace), timeout=DB_GET_HARD_TIMEOUT_S)
    return document

...

async def db_get_fs(collection_name, id, trace):
    try:
        logger.info(f"DB_GET_{trace}: {collection_name}. {id}")
        document = await sync_to_async(fs_collections[collection_name].document(id).get)()

标签: pythongoogle-cloud-firestore

解决方案


目前无法调整 Cloud Firestore 超时值。但是,Firestore 的 Python 客户端库中有一些功能请求[1] [2]要求进行此改进。

另一方面,您只会收到.set()操作错误的事实可能是由于您试图在一秒钟内多次编辑文档

您不应该每秒更新一个文档超过一次。如果您更新文档过快,那么您的应用程序将遇到争用,包括更高的延迟、超时和其他错误。


推荐阅读