NodeJS - MySQL 服务器一段时间后不工作

NodeJS - MySQL server not working after some time

基本上我的 Node.js 服务器与 MySQL 一起工作。当我在本地主机上工作时,一切都很好。与我的本地数据库(我正在使用 XAMPPP)的连接非常好,没有中断。 当服务器由提供商托管时,问题就出现了。我雇用的那个使用 cPanel 并且在一段时间过去之前一切都很好,因为我得到这个错误:

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-30T19_15_37_322Z-debug.log

我一直在研究如何解决这个问题,我得到的唯一有用的答案基本上是说数据库连接正在超时,所以我所要做的就是每隔一段时间发出一个请求,希望它能成功打破。所以我在我的 app.js 文件中写了以下代码:

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

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

虽然这似乎解决了我的问题,但它一遍又一遍地出现(请注意,服务器持续运行的时间确实更长)。

后来有人教我CRON,于是我做了如下CRON:

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

它确实有效,因为它启动了服务器,但它立即崩溃(实际上是在服务器启动后,甚至在服务器成功连接到数据库之后),并记录以下内容:

> 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-30T20_14_02_182Z-debug.log

我不知道还能尝试什么,也没有更多时间,请帮忙!

如果你需要,这里是我的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);

最后,这是我的 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();

在您的 nodejs 程序中使用 mysql connection pool。您的托管服务提供商的廉价且令人讨厌的共享 MySql 服务器具有非常短的空闲连接时间限制。如果您保持打开连接的时间过长,服务器会猛烈关闭它,因此您会收到 ECONNRESET。

为什么? Cyber​​creeps 试图闯入互联网上的随机服务器以获取乐趣和利润。希望这会减慢他们的速度。

如果您

,连接池会在幕后处理这个问题
  1. 在应用程序启动时设置一个池,并且
  2. 在需要时从池中获取一个连接,使用它,然后return将它添加到池中。

或者,您可以跳过连接并在使用完后关闭连接,然后在您再次需要时打开一个新连接。这对于低容量应用程序来说效果很好,但如果您的音量增加,它可能会导致一些低效的连接抖动。游泳池更好。