Как обработать замену хоста mysql в node.js (с tcp keepalive)?
Я пытаюсь решить проблему, когда экземпляр AWS mysql RDS завершается сбоем и инициирует замену хоста, соединения моего приложения узла с этой БД зависают, и, поскольку пул заполнен, новые соединения не устанавливаются (взаимодействие приложения с другими базами данных остается неизменным)
Мне намекали, что проблему можно решить, включив tcp-keepalive для соединений, чтобы сервер узла подтвердил, что соединение не работает, то есть: проверка на наличие мертвых узлов
Я подготовил следующий код для проверки проблемы:
var mysql = require('mysql');
var Net = require('net');
var NetSocket = require('net-keepalive')
// connection pool configuration
var pool = mysql.createPool({
connectionLimit : 10,
connectTimeout : 60 * 60 * 1000,
aquireTimeout : 60 * 60 * 1000,
host : 'mydb.us-east-1.rds.amazonaws.com',
user : 'user',
password : 'password',
dateStrings: true,
multipleStatements: true
});
// connection configuration
pool.on('connection',function(connection) {
socket=connection._socket;
socket.setKeepAlive(true,5 * 60 * 1000);
console.log(NetSocket.getKeepAliveInterval(socket));
console.log(NetSocket.getKeepAliveProbes(socket));
NetSocket.setKeepAliveInterval(socket,10000);
NetSocket.setKeepAliveProbes(socket,3);
console.log(NetSocket.getKeepAliveInterval(socket));
console.log(NetSocket.getKeepAliveProbes(socket));
console.log(socket);
});
// first 8 connections - long query
for (i=1; i<=8; i++) {
pool.query('SELECT * from a_huge_table;', (error, results)=> {
if (error) {
console.log('ERROR:'+error);
}
console.log(new Date(),'RESULT: ', JSON.stringify(results));
});
}
// remaining 1-2 connections - short query every 3 seconds
setInterval(function(){
pool.query('SELECT count(1) from a_small_table;', (error, results)=> {
if (error) {
console.log('ERROR:'+error);
}
console.log(new Date(),'RESULT ', JSON.stringify(results));
});}, 3000);
И следующий процесс тестирования:
- запустить упомянутый скрипт node.js в фоновом режиме
на той же машине контролируйте соединения tcp с помощью:
ss -tmpo | grep "$(dig mydb.us-east-1.rds.amazonaws.com +short)"
с другой машины, вызвать высокую нагрузку на базу данных, вызвать ее сбой и вызвать замену хоста
Из того, что я понимаю до сих пор, с настройками, которые я использовал в приведенном выше коде, после сбоя базы данных должен срабатывать таймер tcp-keepalive, и через 5 минут он будет пытаться отправить 3 проверки активности с интервалом в 10 секунд, и если все они терпят неудачу, возвращают ошибку.
Тем не менее, поведение, которое я испытываю, является неожиданным - после запуска восстановления экземпляра я вижу таймер активности на всех сокетах tcp, отсчитывающий время от 5 минут, а после завершения он либо сбрасывает счетчик снова с 5 минут, либо считает Один раз 10 секунд, а затем снова 5 минут, я наблюдаю за сокетами в течение 30 минут, так как экземпляр полностью восстановлен, и я все еще вижу, как таймеры отключаются и сбрасываются без разрешения
Что мне не хватает?