Django с Peewee Connection Pooling Отключение MySQL - PullRequest
0 голосов
/ 20 ноября 2018

Я запускаю проект Django с Peewee в Python 3.6 и пытаюсь выяснить, что не так с пулом соединений.Я продолжаю получать следующую ошибку на сервере разработки (по какой-то причине у меня никогда не возникало этой проблемы на моем локальном компьютере):

Потерянное соединение с сервером MySQL во время запроса

Действия по воспроизведению надежны:

  1. Перезапустите Apache на экземпляре.
  2. Перейдите на мою страницу Django и нажмите кнопку, которая запускает операцию БД.
  3. Работает нормально.
  4. Подождите ровно 10 минут (я проверил достаточно, чтобы получить точное число).
  5. Нажмите другую кнопку, чтобы запустить другую операцию БД.
  6. Получить потерянныйошибка соединения выше.

Код структурирован таким образом, что у меня есть все операции с БД внутри независимого модуля Python, который импортируется в модуль Django.

В конструкторе основного класса IЯ настраиваю БД следующим образом:

from playhouse.pool import PooledMySQLDatabase

def __init__(self, host, database, user, password, stale_timeout=300):
    self.mysql_db = PooledMySQLDatabase(host=host, database=database, user=user, password=password, stale_timeout=stale_timeout)
    db_proxy.initialize(self.mysql_db)

Каждый вызов, который должен вызывать БД, выполняется следующим образом:

def get_user_by_id(self, user_id):
    db_proxy.connect(reuse_if_open=True)
    user = (User.get(User.user_id == user_id))
    db_proxy.close()
    return {'id': user.user_id, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email }

Я смотрел на wait_timeoutзначение на экземпляре MySQLd его значение равно 3600, так что, похоже, это не проблема (и я все равно пытался изменить его, просто чтобы посмотреть).

Есть идеи, что я мог бы сделать не так?

Обновление:

Я обнаружил, что в файле конфигурации /etc/my.cnf для MySQL значение wait-timeout установлено равным 600, что соответствует тому, что я испытываю.Я не знаю, почему это значение не отображается, когда я запускаю SHOW VARIABLES LIKE 'wait_timeout'; на БД MySQL (который возвращает 3600), но, похоже, проблема возникает из-за тайм-аута ожидания.

Учитывая это, япопытался установить устаревшее время ожидания 60, предполагая, что если оно меньше, чем время ожидания, это может решить проблему, но это не имеет значения.

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Я наконец-то придумал исправление, которое работает для моего случая, после попытки многочисленных идей.Это не идеально, но это работает. Этот пост о пуле соединений указал мне правильное направление.

Я создал класс промежуточного программного обеспечения Django и настроил его в качестве первого в списке промежуточного программного обеспечения Django.

from peewee import OperationalError
from playhouse.pool import PooledMySQLDatabase

database = PooledMySQLDatabase(None)

class PeeweeConnectionMiddleware(object):

    CONN_FAILURE_CODES = [ 2006, 2013, ]

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if database.database: # Is DB initialized?
            response = None
            try:
                database.connect(reuse_if_open=True)
                with database.atomic() as transaction:
                    try:
                        response = self.get_response(request)
                    except:
                        transaction.rollback()
                        raise
            except OperationalError as exception:
                if exception.args[0] in self.CONN_FAILURE_CODES:
                    database.close_all()
                    database.connect()
                    response = None
                    with database.atomic() as transaction:
                        try:
                            response = self.get_response(request)
                        except:
                            transaction.rollback()
                            raise
                else:
                    raise
            finally:
                if not database.is_closed():
                    database.close()
            return response
        else:
            return self.get_response(request)
0 голосов
/ 21 ноября 2018

Необходимо убедиться, что вы правильно перерабатываете соединения - это означает, что когда начинается запрос, вы открываете соединение, а когда ответ доставляется, вы закрываете соединение.Пул не перерабатывает соединение, скорее всего, потому что вы никогда не возвращаете его обратно в пул, так что похоже, что оно все еще «используется».Это легко сделать с помощью промежуточного программного обеспечения, и оно описано здесь:

http://docs.peewee -orm.com / ru / latest / peewee / database.html # django

...