В настоящее время я разрабатываю проект с python 3.7, Django 2.1, Mysql в качестве базы данных.
Я развертываю его в стандартной среде движка облачных приложений Google, а для базы данных я использую облачный SQL — экземпляр MySql 2-го поколения.
Приложение работает хорошо, однако, когда я анализирую логи, я вижу следующие ошибки:
"aborted connection - Got an error reading communication packets"
В этом случае соединение закрывается моим приложением (django). Если я настрою свое приложение на постоянные соединения и поставлю wait_timeout (т.е. 60) в конфигурацию облачного sql, появится ошибка:
"aborted connection - Got timeout reading communication packets".
Я только что определил, что это не проблема с облаком sql или конфигурацией моего приложения, а проблема с механизмом приложения. Я пришел к этому выводу следующим образом:
Итак, мой вывод заключается в том, что проблема заключается в том, как механизм приложения подключается к экземпляру облачного SQL.
Почему это происходит? Как это можно решить?
Я полагаю, это связано с тем, что запросы от приложений App Engine к Cloud SQL зависят от следующего времени и подключения пределы:
Сообщения «Прерванное соединение», которые вы видите, обычно запускаются, когда соединение закрывается неправильно или возникает сетевая аномалия между сервером и клиентом.
Иногда экземпляры Cloud SQL и GAE имеют длительные бездействующие соединения. Чтобы решить эту проблему, рекомендуется установить флаг "ожидание_тайм-аут" менее 600 секунд, поскольку вы уже пытались это сделать.
Другим возможным решением является реализация поддержки активности на уровне приложения. SQLAlchemy предоставляет для этого «предварительный пинг». В противном случае сгенерируйте активность для всех открытых подключений, отправив простую инструкцию SQL, например "SELECT 1;" регулярно, не реже одного раза в 5 минут. Также рассмотрите возможность использования операторов в своем коде, таких как «с db.connect() в качестве подключения:», для управления временем жизни соединения.
@Ale Я запустил пример приложения GAE с помощью Django и подключил его к Cloud SQL, но смог увидеть только несколько таких ошибок. Не могли бы вы поделиться минимальным необходимым кодом, необходимым для воспроизведения проблемы, с которой вы столкнулись? Я считаю, что это поможет определить, где может быть основная причина проблемы.
Какой драйвер mysql вы используете? Раньше я использовал Mysqlclient и перешел на PyMySQL, и количество ошибок резко сократилось. Однако у меня все еще есть сомнения, почему эти ошибки генерируются (поскольку все еще появляются некоторые ошибки)? движок приложения не должен иметь возможность аккуратно закрыть все соединения?
Я запустил пример приложения GAE Django, которое в настоящее время использует PyMySQL 0.9.3. Ошибки могут быть связаны с тем, что соединения не управляются; и рекомендуемый способ избежать их, как вы сказали ранее, — это пул соединений, поскольку App Engine — это среда, в которой выполняется ваш код, она не управляет такими вещами.
Пулинг еще не пробовал. Однако я думаю, что решение не должно заключаться в объединении для этого. Решение должно заключаться в том, что по умолчанию App Engine подключается к базе данных, не генерируя эти ошибки.