当 SSL SYSCALL 错误和 CONN_MAX_AGE > 0 时强制建立新的数据库连接

Posted

技术标签:

【中文标题】当 SSL SYSCALL 错误和 CONN_MAX_AGE > 0 时强制建立新的数据库连接【英文标题】:Forcing new database connection when SSL SYSCALL error and CONN_MAX_AGE > 0 【发布时间】:2015-09-23 05:07:28 【问题描述】:

在带有 Postgres 和 RabbitMQ 的 Heroku 上使用 Django 1.7 和 Celery。

我最近将 Django 中的 CONN_MAX_AGE 设置为 60 左右,这样我就可以开始池化数据库连接了。这工作正常,直到我发现一个问题,如果由于某种原因数据库连接被终止,Celery 将继续使用错误的数据库连接,消耗任务但立即在每个任务中抛出以下错误:

OperationalError: SSL SYSCALL error: Bad file descriptor

我想继续池化数据库连接,但这已经发生了几次,我显然不能让 Celery 随机失败。 如何让 Django(或 Celery)仅在遇到此错误时强制建立新的数据库连接

(或者,我的另一个想法是强制 Celery 工作人员使用修改后的 settings.py 运行,该修改后的 CONN_MAX_AGE=0 仅用于 Celery ......但这感觉很像错误的做法。)

请注意,这个 *** 问题似乎解决了 Rails 上的问题,但我还没有找到 Django 的等价物: On Heroku, Cedar, with Unicorn: Getting ActiveRecord::StatementInvalid: PGError: SSL SYSCALL error: EOF detected

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,并将其归结为 CONN_MAX_AGECELERYD_MAX_TASKS_PER_CHILD 的组合。那时很明显,当替换工作人员时,Celery 没有正确关闭连接,我发现了这个错误报告:https://github.com/celery/celery/issues/2453

升级到 Celery 3.1.18 似乎已经解决了我的问题。

【讨论】:

谢谢,这真的很有帮助。您将CONN_MAX_AGECELERYD_MAX_TASKS_PER_CHILD 设置为什么? 无(意味着数据库连接永远存在)和 20(我发现如果一个工作人员永远运行并处理一系列不同的任务,它最终会导入大量的库并消耗大量的 RAM,即使是很小的任务)。 Django ORM 不是线程/进程安全的,因此 Celery 必须关闭并重新打开每个新工作人员内部的新连接,而这个错误是由错误发生引起的。

以上是关于当 SSL SYSCALL 错误和 CONN_MAX_AGE > 0 时强制建立新的数据库连接的主要内容,如果未能解决你的问题,请参考以下文章

GET 请求在浏览器中工作,但在 curl 中给出错误 SSL_ERROR_SYSCALL

SSL SYSCALL 错误:检测到 EOF

Flutter upgrade升级SDK时报 SSL_ERROR_SYSCALL错误

Flutter upgrade升级SDK时报 SSL_ERROR_SYSCALL错误

Flutter upgrade升级SDK时报 SSL_ERROR_SYSCALL错误

git 使用代理出现 LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 错误