SSL SYSCALL 错误:使用 postgres 和 Celery 的 Heroku 上的文件描述符错误

问题描述 投票:0回答:4

我已经在 Heroku 上的 Django 站点上成功使用了 Celery,但它刚刚开始生成下面的错误,这导致它停止运行。看起来 postgres 遇到了问题,但我对如何修复它感到困惑,因为是 Celery 而不是我的代码有问题(我认为......)。

我使用 CloudAMPQ 作为代理,我的 Django 设置包括:

CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'

这是 Heroku 日志的回溯:

Traceback (most recent call last):
  File "/app/.heroku/python/lib/python3.5/site-packages/kombu/utils/__init__.py", line 323, in __get__
    return obj.__dict__[self.__name__]
KeyError: 'scheduler'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/app/.heroku/python/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.OperationalError: SSL SYSCALL error: Bad file descriptor


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/app/.heroku/python/lib/python3.5/site-packages/billiard/process.py", line 292, in _bootstrap
    self.run()
  File "/app/.heroku/python/lib/python3.5/site-packages/celery/beat.py", line 553, in run
    self.service.start(embedded_process=True)
  File "/app/.heroku/python/lib/python3.5/site-packages/celery/beat.py", line 470, in start
    humanize_seconds(self.scheduler.max_interval))
  File "/app/.heroku/python/lib/python3.5/site-packages/kombu/utils/__init__.py", line 325, in __get__
    value = obj.__dict__[self.__name__] = self.__get(obj)
  File "/app/.heroku/python/lib/python3.5/site-packages/celery/beat.py", line 512, in scheduler
    return self.get_scheduler()
  File "/app/.heroku/python/lib/python3.5/site-packages/celery/beat.py", line 507, in get_scheduler
    lazy=lazy)
  File "/app/.heroku/python/lib/python3.5/site-packages/celery/utils/imports.py", line 53, in instantiate
    return symbol_by_name(name)(*args, **kwargs)
  File "/app/.heroku/python/lib/python3.5/site-packages/djcelery/schedulers.py", line 151, in __init__
    Scheduler.__init__(self, *args, **kwargs)
  File "/app/.heroku/python/lib/python3.5/site-packages/celery/beat.py", line 185, in __init__
    self.setup_schedule()
  File "/app/.heroku/python/lib/python3.5/site-packages/djcelery/schedulers.py", line 158, in setup_schedule
    self.install_default_entries(self.schedule)
  File "/app/.heroku/python/lib/python3.5/site-packages/djcelery/schedulers.py", line 251, in schedule
    self._schedule = self.all_as_schedule()
  File "/app/.heroku/python/lib/python3.5/site-packages/djcelery/schedulers.py", line 164, in all_as_schedule
    for model in self.Model.objects.enabled():
  File "/app/.heroku/python/lib/python3.5/site-packages/django/db/models/query.py", line 258, in __iter__
    self._fetch_all()
  File "/app/.heroku/python/lib/python3.5/site-packages/django/db/models/query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/app/.heroku/python/lib/python3.5/site-packages/django/db/models/query.py", line 52, in __iter__
    results = compiler.execute_sql()
  File "/app/.heroku/python/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 848, in execute_sql
    cursor.execute(sql, params)
  File "/app/.heroku/python/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/app/.heroku/python/lib/python3.5/site-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/app/.heroku/python/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/app/.heroku/python/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.OperationalError: SSL SYSCALL error: Bad file descriptor
django postgresql heroku celery
4个回答
1
投票

我现在已经解决了这个问题...我的 Django 代码中有一行在过去导致了内部服务器错误 - 我认为,在 Django 启动的早期,它试图在创建模型的迁移已经运行。

我已经解决了这个问题,但注意到这些“SSL SYSCALL 错误”大约在同一时间开始。所以我删除了那行代码,Celery 又启动了。

这可能是巧合。我不明白为什么这会解决问题。

理想情况下,我仍然想了解上面的错误实际上意味着什么,这样我将来就有更好的机会解决这样的问题。


0
投票

我有同样的错误,我解决了。 就我而言,问题是我的 django 应用程序之一中的自定义 AppConfig。

我的文件夹

my_django_app/
  __init__.py
  apps.py
  ...

我有一个文件

my_django_app/__init__.py
像这样

default_app_config="my_django_app.apps.MyAppConfig"

和文件

my_django_app/apps.py
像这样

class ChallengeConfig(AppConfig):
    
    name = 'appConfig'
    verbose_name = "djangoAppConfig"

    def ready(self):
        ... # custom logic

去掉线后

default_app_config="my_django_app.apps.MyAppConfig"
芹菜又可以工作了

如果您有类似的情况,请删除自定义 AppConfig 并使用 celery 定期任务而不是自定义 AppConfig。 django_celery_beat 对 AppConfig 做了一些奇怪的事情,所以如果你有一个自定义的 AppConfig 它会产生问题

我的Python要求:

Django==1.11.29
celery==4.4.7
django_celery_beat==1.6.0

0
投票

我知道这是几年前提出的问题,但这是唯一与我的问题相关的问题。

在我的例子中,CONN_MAX_AGE 设置为 600。减少到 0,以便有无限的持久连接。

来自文档:

持久连接避免了在每个请求中重新建立与数据库的连接的开销。它们由 CONN_MAX_AGE 参数控制,该参数定义连接的最大生命周期。每个数据库都可以独立设置。

默认值为0,保留每次请求结束时关闭数据库连接的历史行为。要启用持久连接,请将 CONN_MAX_AGE 设置为正整数(秒)。对于无限制的持久连接,请将其设置为 None。

Django 在第一次进行数据库查询时打开与数据库的连接。它保持此连接打开并在后续请求中重用它。一旦连接超过 CONN_MAX_AGE 定义的最大期限或不再可用,Django 就会关闭连接。

详细来说,每当 Django 需要但还没有数据库连接时,它就会自动打开一个到数据库的连接 - 要么因为这是第一个连接,要么因为上一个连接已关闭。

在每个请求开始时,如果连接已达到最大寿命,Django 将关闭连接。如果您的数据库在一段时间后终止空闲连接,您应该将 CONN_MAX_AGE 设置为较低的值,以便 Django 不会尝试使用已被数据库服务器终止的连接。 (这个问题可能只影响流量非常低的网站。)

在每个请求结束时,如果连接已达到最长期限或处于不可恢复的错误状态,Django 将关闭连接。如果在处理请求时发生任何数据库错误,Django 会检查连接是否仍然有效,如果不有效则将其关闭。因此,数据库错误最多影响一个请求;如果连接变得不可用,下一个请求将获得新的连接。


0
投票

我们有一个非常相似的错误消息,并且几乎有相同的堆栈(Heroku、Django、Celery、Postgres)。我们的问题是由于模块加载时的数据库调用造成的。我们的其中一种表格如下所示:

class BatteryForm(forms.Form):
    battery = forms.ModelMultipleChoiceField(
        label='Battery type',
        required=True,
        queryset=Battery.objects.all(),
        initial=[Battery.objects.get(name='battery-name')],
        widget=forms.CheckboxSelectMultiple,
    )

initial 中的值在模块加载时进行了数据库调用,以

SSL SYSCALL error
结尾,但仅限于 Celery 工作人员。

我不知道为什么会发生这种情况,或者只在生产中引起问题,但看看其他答案,很可能是在启动应用程序时与数据库通信。

© www.soinside.com 2019 - 2024. All rights reserved.