MySQL дает ошибку "read ECONNRESET" после простоя на сервере node.js
Я использую Node-сервер, подключающийся к MySQL через модуль node-mysql. Первоначально, без каких-либо ошибок, подключение к MySQL и выполнение запросов к нему прекрасно работает, однако первый запрос, если сервер Node не используется в течение нескольких часов, приводит к ошибке. Ошибка знакомая read ECONNRESET
исходя из глубины модуля node-mysql.
Трассировка стека (обратите внимание, что три записи трассировки принадлежат к коду сообщения об ошибках моего приложения):
Error
at exports.Error.utils.createClass.init (D:\home\site\wwwroot\errors.js:180:16)
at new newclass (D:\home\site\wwwroot\utils.js:68:14)
at Query._callback (D:\home\site\wwwroot\db.js:281:21)
at Query.Sequence.end (D:\home\site\wwwroot\node_modules\mysql\lib\protocol\sequences\Sequence.js:78:24)
at Protocol.handleNetworkError (D:\home\site\wwwroot\node_modules\mysql\lib\protocol\Protocol.js:271:14)
at PoolConnection.Connection._handleNetworkError (D:\home\site\wwwroot\node_modules\mysql\lib\Connection.js:269:18)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:415:13)
Эта ошибка происходит как на моем облачном сервере Node, так и на сервере MySQL, а также при локальной настройке обоих.
Мои вопросы:
Эта проблема, кажется, является разъединением соединения Node с моими серверами MySQL, возможно из-за ограничения времени жизни соединения?
При использовании пулов соединений node-mysql должен корректно обрабатывать разъединения и удалять их из пула. Разве он не знает об отключении, пока я не сделаю запрос, что делает ошибку неизбежной?
Учитывая, что я часто вижу ошибку "read ECONNRESET" в других сообщениях Stackru, мне следует искать в MySQL в другом месте, чтобы диагностировать проблему?
Обновление: после более продолжительного просмотра, я думаю, что моя проблема является дубликатом этого. Похоже, что его соединение также разъединяется, но никто не предложил, как сохранить соединение живым или как устранить ошибку, за исключением сбоя первого запроса назад.
4 ответа
Я связался с ребятами из node-mysql на их странице в Github и получил твердые ответы.
MySQL действительно удаляет простаивающие соединения. Есть переменная MySQL "wait_timeout", которая устанавливает количество секунд до истечения времени ожидания, и по умолчанию это 8 часов. Мы можем установить значение по умолчанию намного больше, чем это. использование
show variables like 'wait_timeout';
чтобы просмотреть настройки тайм-аута иset wait_timeout=28800;
изменить это.Согласно этой проблеме, node-mysql не сокращает соединения пула после такого рода отключений. Разработчики модуля рекомендовали использовать сердцебиение, чтобы поддерживать соединение, такое как вызов
SELECT 1;
на интервале. Они также рекомендовали использовать модуль пула узлов и его опцию idleTimeoutMillis для автоматического сокращения незанятых соединений.
Если это происходит при установлении одного повторно используемого соединения, этого можно избежать, создав вместо этого пул соединений.
Например, если вы делаете что-то вроде этого...
var db = require('mysql')
.createConnection({...})
.connect(function(err){});
сделай это вместо этого...
var db = require('mysql')
.createPool({...});
Эта проблема, кажется, является разъединением соединения Node с моими серверами MySQL, возможно из-за ограничения времени жизни соединения?
Да. Сервер закрыл свой конец соединения.
При использовании пулов соединений node-mysql должен корректно обрабатывать разъединения и удалять их из пула. Разве он не знает об отключении, пока я не сделаю запрос, что делает ошибку неизбежной?
Исправьте, но это должно обработать ошибку внутри, а не передавать ее вам. Это похоже на ошибку в node-mysql. Доложите об этом.
Учитывая, что я часто вижу ошибку "read ECONNRESET" в других сообщениях Stackru, мне следует искать в MySQL в другом месте, чтобы диагностировать проблему?
Это либо ошибка в реализации пула соединений нода-MySQL, либо вы неправильно настроили ее для обнаружения сбоев.
Я также столкнулся с той же проблемой. По-видимому, это происходило из-за того, что один из внутренних процессов был запущен для таблицы, на которую ссылался мой API.
Это привело к тому, что таблица перешла в состояние ожидания блокировки, и мой запрос запроса не удался при сбросе соединения. Хотя мне интересно, почему я не получил ошибку ожидания блокировки.