Я работаю с Django 2.2.6.
В той же системе, в которой работает мой проект django, также работает фоновая служба, прослушивающая сокет unix для запросов. В Django Admin, если пользователь нажимает кнопку, Django отправляет запрос на сокет unix, и фоновая служба что-то делает.
Моя фоновая служба имеет полный доступ к Django ' с ОРМ. Он импортирует модели из файла models.py моего проекта и может без проблем запрашивать базу данных.
Проблема заключается в том, что если я оставлю свой django и мою фоновую службу запущенной на ночь, войдите в систему Django Admin и, нажав кнопку, моя фоновая служба выдает исключение:
django.db.utils.OperationalError: (2006, 'MySQL server has gone away')
Похоже, это потому, что база данных MySQL имеет период ожидания, называемый wait_timeout
. Если соединение с базой данных не активно в течение этого времени, MySQL отключит его. К сожалению, Django не замечает и пытается использовать его, выдавая ошибку.
К счастью, Django имеет собственную встроенную переменную CONN_MAX_AGE для каждой базы данных, определенной в settings.py. Если подключение к базе данных старше, чем CONN_MAX_AGE, оно закрывает его перед запросом и запускает новое.
Просмотр моей базы данных MySQL:
> show session variables where variable_name = "wait_timeout";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |
+---------------+-------+
Просмотр моего Переменная Django CONN_MAX_AGE:
# ./manage.py shell
>>> from django.conf import settings
>>> settings.DATABASES['default']['CONN_MAX_AGE']
0
Примечание: база данных по умолчанию - единственная, которую я определил в моих settings.py
Также обратите внимание, что обе мои MySQL wait_timeout, и мои Django CONN_MAX_AGE являются значениями по умолчанию - я не изменил их.
Согласно Django документам здесь , значение CONN_MAX_AGE 0 означает:
закрывать соединения с базой данных в конце каждого запроса
Если django предназначено для закрытия соединения с базой данных после каждого запроса, почему я столкнулся с этой ошибкой? Почему он не закрывает старые соединения, как только я закончу свой запрос и запускаю новое соединение, когда я делаю новый запрос, спустя несколько часов?
Редактировать:
Прямо сейчас, мое решение состоит в том, чтобы фоновая служба делала биение сердца. Кажется, один раз в час работает нормально. Сердцебиение - это простая команда с низким потреблением ресурсов MySQL, такая как MyDjangoModel.objects.exists (). Пока он выполняет запрос MySQL для восстановления sh таймаута MySQL, он работает. Это усложняет мою фоновую службу, так как в одном случае моей однопоточной фоновой службе в противном случае требовался фоновый поток, единственной задачей которого было выполнение тактов.
Если есть более простое решение, или по крайней мере, объяснение того, почему это происходит, я бы хотел услышать это.