В настоящее время я занимаюсь разработкой проекта с Python 3.7, Django 2.1, Mysql в качестве базы данных.

Я развертываю его в стандартной среде движка облачных приложений Google, а для базы данных использую облачный SQL - экземпляр MySql 2-го поколения.

Приложение работает хорошо, однако, когда я анализирую журналы, я вижу эти ошибки:

"прервано соединение - ошибка чтения пакетов связи"

В этом случае соединение закрывается моим приложением (django). Если я настраиваю свое приложение на наличие постоянных соединений и помещаю wait_timeout (т.е. 60) в конфигурацию облака sql, ошибка:

msgstr "прервано соединение - получен тайм-аут чтения пакетов связи".

Я только что определил, что это не проблема с облаком SQL или конфигурацией моего приложения, а проблема с механизмом приложения. Я пришел к такому выводу следующим образом:

  • если я подключаюсь к экземпляру облака SQL через Mysql Workbench, соединение не прерывается
  • Точно так же, если я запускаю свое приложение на локальном сервере, но подключаюсь к облаку SQL (через cloud_sql_proxy), ошибка не генерируется, и все работает отлично.

Итак, мой вывод заключается в том, что проблема заключается в том, как ядро приложения подключается к экземпляру облака SQL.

Почему это происходит? Как это можно решить?

1
ozo 30 Май 2019 в 19:38

2 ответа

Лучший ответ

Сообщения «Прерванное соединение», которые вы видите, обычно запускаются, когда соединение закрывается ненадлежащим образом или возникает сетевая аномалия между сервером и клиентом.

  • Иногда экземпляры Cloud SQL и GAE имеют долгоживущие простаивающие соединения. Для решения этой проблемы рекомендуется установить "wait_timeout" меньше 600 секунд - как вы уже пытались это сделать.

  • Другим возможным решением является реализация средств поддержки активности на уровне приложений. SQLAlchemy предоставляет предварительную проверку для этот. В противном случае создайте активность для всех открытых соединений, отправив простой оператор SQL, такой как «SELECT 1;» регулярно, не реже одного раза в 5 минут. Также рассмотрите возможность использования в своем коде операторов, таких как "с db.connect () в качестве conn: "для контроля времени жизни соединения.

2
Maxim 31 Май 2019 в 10:07

Я полагаю, что это потому, что запросы приложений App Engine к облачному SQL подлежат следующему времени и подключению пределы :

  • Для приложений, работающих в стандартной среде App Engine, все запросы к базе данных должны завершаться в таймере HTTP-запроса, около 60 секунд. Для приложений, работающих в гибкой среде, все запросы к базе данных должны завершаться в течение 60 минут.
  • Оффлайн-запросы, такие как задачи cron, имеют ограничение по времени 10 минут.
  • Запросы к облачному SQL имеют ограничения, основанные на типе масштабирования модуля App Engine и времени, в течение которого экземпляр может оставаться в памяти (место жительства).
  • Каждый экземпляр App Engine, работающий в стандартной среде, не может иметь более 60 одновременных подключений к экземпляру Cloud SQL. Для приложений, написанных на Java 8 или Go 1.8, ограничение составляет 100.
  • Проблемы с подключением: Если вы видите ошибки, содержащие «Прерванное соединение nnnn» to db: ", это обычно означает, что ваше приложение не прерывает соединения должным образом. Это также может быть вызвано проблемами с сетью. Эта ошибка не означает, что существуют проблемы с вашим экземпляром Cloud SQL.
1
John Frederick Dupale 31 Май 2019 в 07:44
56382242