gpt4 book ai didi

django - 在线程中使用 Django ORM 并通过使用 BoundedSemaphore 避免 "too many clients"异常

转载 作者:行者123 更新时间:2023-11-29 11:15:47 24 4
gpt4 key购买 nike

我使用 manage.py 命令创建大约 200 个线程来检查远程主机。我的数据库设置允许我使用 120 个连接,所以我需要使用某种池。我试过使用单独的线程,像这样

class Pool(Thread):
def __init__(self):
Thread.__init__(self)
self.semaphore = threading.BoundedSemaphore(10)

def give(self, trackers):
self.semaphore.acquire()
data = ... some ORM (not lazy, query triggered here) ...
self.semaphore.release()
return data

我将此对象的实例传递给每个检查线程,但在初始化 120 个线程后仍然在 Pool 对象中出现“OperationalError: FATAL: sorry, too many clients already”。我预计只会打开 10 个数据库连接,并且线程会等待空闲的信号量槽。我可以通过注释“release()”来检查信号量是否工作,在这种情况下,只有 10 个线程可以工作,其他线程将等到应用程序终止。

据我所知,即使实际调用是在不同的线程中,每个线程都会打开与数据库的新连接,但为什么呢?有没有办法在一个线程内执行所有数据库查询?

最佳答案

Django 的 ORM 在线程局部变量中管理数据库连接。因此,访问 ORM 的每个不同线程都将创建自己的连接。您可以在 django/db/backends/__init__.py 的前几行中看到这一点。

如果要限制建立的数据库连接数,则必须限制实际访问 ORM 的不同线程数。一个解决方案可能是实现一个服务,将 ORM 请求委托(delegate)给一个专用的 ORM 线程池。要将请求及其结果从其他线程传输到其他线程,您将必须实现某种消息传递机制。由于这是一个典型的生产者/消费者问题,关于线程的 Python 文档应该给出一些如何实现这一点的提示。

编辑: 我刚刚在 google 上搜索了“django 连接池”。有很多人提示 Django 没有提供合适的连接池。他们中的一些人设法集成了一个单独的池包。对于 PostgreSQL,我会看一下 pgpool 中间件。

关于django - 在线程中使用 Django ORM 并通过使用 BoundedSemaphore 避免 "too many clients"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3435673/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com