Django выбрасывает ошибку "соединение с базой данных уже закрыто" на задаче Scrapy + Celery

Context

У меня есть приложение Django, запущенное внутри контейнера Docker. Это приложение использует Celery и Celery-beat для асинхронных и запланированных задач. Одна из этих задач собирает тексты с различных веб-сайтов с помощью Scrapy. Эта задача выполняется каждую минуту и ищет новые тексты на страницах. Если есть новая информация, она создает новый объект в MyModel. Эта логика (запрос к базе данных для проверки существования данных, создание объекта или обновление информации) выполняется пользовательским конвейером элементов Scrapy.

Выпуск

При использовании среды разработки (с помощью локального Docker Compose для включения одного контейнера для приложения, одного контейнера для PostgreSQL и других контейнеров служб) все работает гладко. Однако при использовании среды Stage (один контейнер Docker для приложения на дроплете DigitalOcean и самоуправляемый кластер PostgreSQL) задачи выдают такую ошибку:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 237, in _cursor
    return self._prepare_cursor(self.create_cursor(name))
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 236, in create_cursor
    cursor = self.connection.cursor()
psycopg2.InterfaceError: connection already closed

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

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/twisted/internet/defer.py", line 857, in _runCallbacks
    current.result = callback(  # type: ignore[misc]
  File "/usr/local/lib/python3.8/site-packages/scrapy/utils/defer.py", line 150, in f
    return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
  File "/sites/app/services/scraper/news/pipelines.py", line 145, in process_item
    existing_article = check_if_existing_article(item)
  File "/sites/app/services/scraper/news/pipelines.py", line 124, in check_if_existing_article
    if ProcessedArticle.objects.filter(
  File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 809, in exists
    return self.query.has_results(using=self.db)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/query.py", line 537, in has_results
    return compiler.has_results()
  File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1126, in has_results
    return bool(self.execute_sql(SINGLE))
  File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1154, in execute_sql
    cursor = self.connection.cursor()
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 259, in cursor
    return self._cursor()
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 237, in _cursor
    return self._prepare_cursor(self.create_cursor(name))
  File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 237, in _cursor
    return self._prepare_cursor(self.create_cursor(name))
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 236, in create_cursor
    cursor = self.connection.cursor()
django.db.utils.InterfaceError: connection already closed

Дополнительная информация

  • Подключение к БД кажется стабильным, потому что во всем приложении нет других проблем, и мы используем только один кластер
  • .
  • Если я помещаю в тот же скрипт db.connections.close_all() перед запросами, он работает в течение пары минут, но потом отказывает.
  • После того, как он отказал один раз, он продолжает отказывать все время.
  • DO Метрика базы данных: [введите здесь описание изображения][1]

Есть подсказка?

Заранее спасибо!

Вернуться на верх