es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

NodeJS – el servidor MySQL deja de funcionar después de un tiempo

Básicamente tengo funcionando mi servidor Node.js junto con MySQL. Cuando trabajo en mi localhost, todo va bien. La conexión a mi base de datos local (estoy usando XAMPP) es genial y nada falla. El problema surge cuando el servidor es contratado por un proveedor. El que contraté usa cPanel y todo va bien hasta que pasa algún tiempo, porque obtengo este error:

events.js:377
  throw er; // Unhandled 'error' event
  ^

Error: read ECONNRESET
    at TCP.onStreamRead (internal/stream/base_commons.js:209:20)
Emitted 'error' event on Connection instance at:
    at Connection.handleProtocolError (/home/adminis6/Artesofa/node_modules/mysql/lib/Connection.js:423:8)
    at Protocol.emit (events.js:400:28)
    at Protocol.delegateError (/home/adminis6/Artesofa/node_modules/mysql/lib/protocol/Protocol.js:398:10)
    at Protocol.handleNetworkError (/home/adminis6/Artesofa/node_modules/mysql/lib/protocol/Protocol.js:371:10)
    at Connection.handleNetworkError (/home/adminis6/Artesofa/node_modules/mysql/lib/Connection.js:418:18)
    at Socket.emit (events.js:400:28)
    at emitErrorNT (internal/streams/destroy.js:106:8)
    at emitErrorCloseNT (internal/streams/destroy.js:74:3)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  errno: -104,
  code: 'ECONNRESET',
  syscall: 'read',
  fatal: true
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! amor-muebles@1.0.0 start: `node app.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the amor-muebles@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/adminis6/.npm/logs/2021-11-30T191537322Z-debug.log

He estado investigando cómo solucionar este problema y la única respuesta útil que recibí básicamente dijo que la conexión a la base de datos se estaba agotando, así que todo lo que tenía que hacer era hacer una solicitud a intervalos y esperar que no se rompiera. Así que escribí el siguiente código en mi archivo app.js:

const fetch = require("node-fetch");

setInterval(() => {
    fetch('sample-endpoint');
}, 30000);

Aunque esto parecía haber resuelto mi problema, apareció una y otra vez (note que el servidor duró más tiempo en funcionamiento).

Más tarde, algunas personas me enseñaron sobre los CRON, así que hice el siguiente CRON:

PATH=$PATH:$HOME/bin; export PATH; /usr/bin/pgrep "node" > /dev/null || (cd /home/adminis6/Artesofa/; pkill node; pkill npm; nohup npm start &)

Y funciona, porque activa el servidor, pero instantáneamente se detiene (literalmente justo después de que el servidor se inicie, incluso después de que el servidor se conecta a la base de datos con éxito), y registra lo siguiente:

> amor-muebles@1.0.0 start /home/adminis6/Artesofa
> node app.js

Server running on port 3100 
mysql connected
events.js:377
  throw er; // Unhandled 'error' event
  ^

Error: read ECONNRESET
    at TCP.onStreamRead (internal/stream/base_commons.js:209:20)
Emitted 'error' event on Connection instance at:
    at Connection.handleProtocolError (/home/adminis6/Artesofa/node_modules/mysql/lib/Connection.js:423:8)
    at Protocol.emit (events.js:400:28)
    at Protocol.delegateError (/home/adminis6/Artesofa/node_modules/mysql/lib/protocol/Protocol.js:398:10)
    at Protocol.handleNetworkError (/home/adminis6/Artesofa/node_modules/mysql/lib/protocol/Protocol.js:371:10)
    at Connection.handleNetworkError (/home/adminis6/Artesofa/node_modules/mysql/lib/Connection.js:418:18)
    at Socket.emit (events.js:400:28)
    at emitErrorNT (internal/streams/destroy.js:106:8)
    at emitErrorCloseNT (internal/streams/destroy.js:74:3)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  errno: -104,
  code: 'ECONNRESET',
  syscall: 'read',
  fatal: true
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! amor-muebles@1.0.0 start: `node app.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the amor-muebles@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/adminis6/.npm/logs/2021-11-30T201402182Z-debug.log

¡No sé qué más intentar ni tengo mucho más tiempo, por favor ayuda!

Si la necesitas, aquí está mi app.js:

/* ----------- Server initialization ----------- */
//Here are all the modudule's require

const app = express();

// Connect to mySQL DB
const db = require('./db/connectDB');

// Set server to listen on specified port
app.listen(process.env.PORT || '4000', () => {
    console.log(`Server running on port ${process.env.PORT} AAAAA`);
})

app.set('view engine', 'ejs');
app.use(express.static('public'));

app.set('views', [
    path.join(__dirname, 'views/adminSite/')
]);

/* ----------- Middleware ----------- */

app.use(express.urlencoded({ extended: true }));
app.use(helmet());
app.use(cookieParser());
app.use(morgan('tiny'));

/* ----------- Routes ----------- */

app.use('/api', apiRoutes);

setInterval(() => {
    fetch('https://administracionartesofa.com/api/sucursales');
}, 30000);

Y, finalmente, aquí está mi archivo connectDB:

const mysql = require('mysql');
const dotenv = require('dotenv').config();
const settings = process.env.ENV === 'dev' ? require('./devSettings.json') : require('./prodSettings.json');

let db;

const connectDatabase = () => {
    if (!db) {
        db = mysql.createConnection(settings);

        db.connect((err) => {
            if (err) {
                console.log('Database error');
                console.log(err);
                connectDatabase();
            } else {
                console.log('mysql connected');
            }
        })
    }
    return db;
}

module.exports = connectDatabase();
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución de problemas del error ECONNRESET en la conexión MySQL

    El error ECONNRESET es un problema común al trabajar con MySQL y Node.js, especialmente al alojar el servidor en un proveedor de terceros. Este error ocurre cuando el servidor cierra abruptamente la conexión o expira mientras espera una respuesta. Aquí están los pasos para solucionar el error ECONNRESET en una conexión MySQL:

    1. Verificar el estado del servidor MySQL

    Asegúrese de que el servidor MySQL esté en funcionamiento y sea accesible en la máquina host. Verifique el nombre de host, el puerto, el nombre de usuario y la contraseña en su código.

    2. Aumentar el tiempo de espera de conexión

    Una forma de evitar el error ECONNRESET es aumentar el tiempo de espera de conexión en su código de Node.js. Configure la opción de tiempo de espera en la configuración de la conexión MySQL a un valor más alto, por ejemplo, 10 segundos.

    const dbConfig = {
      host: 'localhost',
      user: 'root',
      password: 'contraseña',
      database: 'basededatostest',
      timeout: 10000 // 10 segundos
    };
    

    3. Usar un pool de conexiones

    Utilizar un pool de conexiones puede ayudar a administrar la conexión a la base de datos MySQL y manejar los tiempos de espera de conexión. El pool de conexiones mantiene un grupo de conexiones que la aplicación puede usar repetidamente sin crear una nueva conexión cada vez. Aquí hay un ejemplo:

    const mysql = require('mysql');
    
    const pool = mysql.createPool({
      connectionLimit: 10,
      host: 'localhost',
      user: 'root',
      password: 'contraseña',
      database: 'basededatostest',
      timeout: 10000 // 10 segundos
    });
    
    pool.getConnection((err, connection) => {
      if (err) throw err;
      console.log('Conectado');
      // Ejecutar la consulta y liberar la conexión
      connection.query('SELECT * FROM usuarios', (error, results, fields) => {
        connection.release();
        if (error) throw error;
        console.log(results);
      });
    });
    

    4. Usar setInterval para mantener el servidor activo

    Como mencionó el autor, usar setInterval para realizar una solicitud regular al servidor puede evitar que expire. Sin embargo, esta solución no es ideal ya que puede poner una carga en el servidor y el cliente también puede experimentar retrasos o un tiempo de respuesta lento.

    5. Usar CRON para reiniciar el servidor

    Se puede programar un trabajo CRON para supervisar el servidor y reiniciarlo si se detiene. El autor mencionó el uso de CRON para reiniciar el servidor, pero no funciona correctamente. Es importante revisar los archivos de registro para depurar e identificar los problemas.

    En conclusión, el error ECONNRESET es un problema común en las conexiones MySQL y varios factores podrían causarlo. Recomendamos el uso de un pool de conexiones o aumentar el tiempo de espera de conexión como medida preventiva. Además, el uso de un CRON para supervisar el servidor y automatizar el proceso de reinicio podría ser una solución viable.

Comments are closed.