问题描述
我们有一个Django应用程序,该应用程序必须定期使用第三方API才能为一组用户获取大量数据。任务执行得很好,并实现了其目标。但是一段时间后,我们开始从postgres中收到太多连接错误
致命:对不起,已经有太多客户了
信息
该项目已被docker化,所有组件都在单独的容器中运行,包括应用程序和数据库(postgres)。定期任务使用dramatiq执行,并按periodiq计划。 我们还将redis用作系统代理。
我尝试了各种变通方法以使其停止运行,但没有一个方法起作用,包括SO中提出的各种解决方案。
尝试1
在每次执行任务之前,我都使用connection.closes()
之前和之后,以确保工人没有断开连接。
尝试2
添加任务限制器,以限制给定时间的活动连接数,并防止数据库不堪重负。尽管此解决方案显然不能满足我们实现的实际范围,但会降低任务执行的性能,但对解决问题没有帮助。
尝试3
增加Postgres的池限制。按照建议的here,我添加了一个自定义配置文件以增加可用的缓冲池。这是有效果的,但是它只是推迟了错误的显示,并不能避免这种错误的发生。我什至达到了非常高的10K连接限制(从默认的10个开始)。如果有帮助,我会在此处发布配置文件。
注意:该应用程序在具有24个核心和128GB RAM的服务器上运行,并且在执行任务时不会使用超过1%的资源。
max_connections = 100000
shared_buffers = 64GB
尝试4
我已将pgpool插入到项目中,以便将对数据库的请求排队。这可以防止数据库不堪重负,但这不是一个实际的解决方案,因为它导致数据库连接永远等待,并且也使数据库可用。
尝试5
使用CONN_MAX_AGE=0
parameter来防止Django创建持久连接。那也没有效果。
尝试6
尝试使任务在atomic connection block上运行。这似乎也没有帮助。
我认为,在Dramatiq Worker上并行线程中执行任务的方式会导致连接保持打开状态但处于空闲状态。我试图手动关闭Dramatiq和periodiq容器的连接,但这在解决连接池问题上几乎没有用。
我尝试了在SO上发现的所有变体。
# Command 1
connection.close
# Command 2
for c in connections.all():
c.close()
# Command 3
close_old_connections()
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)