Когда проверяется/используется Djangos CONN_MAX_AGE?
Недавно у меня возникла проблема "Слишком много соединений" моего приложения Django+Celery с БД Postgres на Heroku.
Может ли проблема заключаться в перезапуске диноскопа? Идея заключается в том, что перезапуск dyno разрывает соединение, но Postgres сохраняет их.
Установка CONN_MAX_AGE
, кажется, решила проблему, но я не уверен.
Теперь вопрос заключается в следующем: Как работает CONN_MAX_AGE
?
(1) Активно ли Django проверяет возраст соединения и закрывает + перезапускает его, когда оно слишком старое
или
(2) Является ли CONN_MAX_AGE
параметром самого соединения, так что postgres автоматически закрывает соединение по истечении этого времени?
Активно ли Django проверяет возраст соединения и закрывает + перезапускает его, если оно слишком старое.
Django будет каждый раз, когда открывает соединение, устанавливать время, когда он должен закрыть соединение [GitHub]:
class BaseDatabaseWrapper: # … @async_unsafe def connect(self): # … max_age = self.settings_dict["CONN_MAX_AGE"] self.close_at = None if max_age is None else time.monotonic() + max_age
Затем, когда будет вызван метод с именем .close_if_unusable_or_obsolete()
, Django закроет соединение [GitHub]:
class BaseDatabaseWrapper: # … def close_if_unusable_or_obsolete(self): # … if self.connection is not None: # … if self.close_at is not None and time.monotonic() >= self.close_at: self.close() return
You can call that method yourself to "recycle" connections. But it is by default done when a request starts and when a request ends, indeed Django registers this on two signals [GitHub]:
def close_old_connections(**kwargs): for conn in connections.all(initialized_only=True): conn.close_if_unusable_or_obsolete() signals.request_started.connect(close_old_connections) signals.request_finished.connect(close_old_connections)
Таким образом, до выполнения запроса он будет перерабатывать соединения, а после выполнения запроса - перерабатывать соединения с неустранимыми ошибками или устаревшие. Утилизация в середине запроса может быть не очень хорошей идеей, поскольку соединение может быть государственным.