繁体   English   中英

在 Windows 平台 PM2 上不支持 Node.js 的“正常关机”

[英]On windows platform PM2 not supporting Node.js for "Graceful Shutdown"

我试过这种方式 -

const server = app.listen(port, () => console.log('Project running on port ' + port));

process.on('SIGINT', () => {
  console.info('SIGINT signal received.')

  // Stops the server from accepting new connections and finishes existing connections.
  server.close(function(err) {
    // if error, log and exit with error (1 code)
    if (err) {
      console.error(err)
      process.exit(1)
    }

    // close your database connection and exit with success (0 code)
    // for example with mongoose
    mongoose.connection.close(function () {
      console.log('Mongoose connection disconnected')
      process.exit(0)
    })
  })
})

第二种方式也是 -

const server = app.listen(port, () => console.log('Project running on port ' + port));

process.on('message', function(msg) {

  console.info('shutdown signal received.',msg)
  if (msg == 'shutdown') {
    console.log('Closing all connections...');
    setTimeout(function() {
      console.log('Finished closing connections');
      process.exit(0);
    }, 1500);
  }
});

但两者都没有帮助。

我从阅读所有相关的开放类似问题中了解到的是 PM2 而不是向节点发送“SIGINT”信号,它自己杀死它。

我们可以自己制作一个 bash 脚本,而不是使用 pm2,如果关闭时出现一些错误,它将重新启动我们的节点项目。

 @echo off setlocal enableextensions enabledelayedexpansion set /a "x = 0" :more_to_process if %x% leq 10 ( echo %x% node E:\\Max\\Projects\\dummy\\API\\server.js set /a "x = x + 1" goto :more_to_process ) endlocal pause

以上脚本重试 10 次以重新启动 API。 可以更改重试时间。

现在制作日志文件和处理错误,我们可以做

 const server = app.listen(port, () => console.log('Dummy-App API running on port ' + port)); var fs = require('fs'); var util = require('util'); var path = __dirname + `/mylogfiles/debug(${getDate()}).log`, printNextLine = false if(fs.existsSync(path)){ printNextLine = true } var log_file = fs.createWriteStream(path, {flags : 'a'}); /* 'a' : open the file for writing, positioning the stream at the end of the file. The file is created if not existing 'a+' : open the file for reading and writing, positioning the stream at the end of the file. The file is created if not existing 'r+' : open the file for reading and writing 'w+' : open the file for reading and writing, positioning the stream at the beginning of the file. The file is created if not existing (you can find more flags at https://nodejs.org/api/fs.html#fs_file_system_flags) */ if(printNextLine == true){ let prnt = '***************************************************************************************************************' log_file.write('\\n' + '\\n' + prnt + '\\n'); } var log_stdout = process.stdout; console.log = function(d) { // log_file.write((new Date).toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' }) + ' | ' + util.format(d) + '\\n'); log_stdout.write( util.format(d) + '\\n'); }; console.error = function(d) { // log_file.write((new Date).toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' }) + ' | ' + util.format(d) + '\\n'); log_stdout.write( util.format(d) + '\\n'); }; process.on('uncaughtException', function (err) { console.error(err) // console.error((new Date).toUTCString() + ' uncaughtException:', err.message) // console.error(err.stack) process.exit(1) }) function getDate(addDay){ let mydate = new Date() var month = mydate.getMonth() + 1; // month (in integer 0-11) var year = mydate.getFullYear(); // year var date = mydate.getDate() let h = mydate.getHours() let m = mydate.getMinutes() let s = mydate.getSeconds() // let desiredDate = `${year}.${month}.${date} H-${h} M-${m} S-${s}` let desiredDate = `${year}.${month}.${date}` return desiredDate }
请创建一个名为“mylogfiles”的文件夹,与 server.js/index.js 文件平行。

现在,“正常关机”还剩下什么:-

 process.on('SIGINT', () => { console.info('SIGINT signal received.') // Stops the server from accepting new connections and finishes existing connections. server.close(function(err) { // if error, log and exit with error (1 code) if (err) { console.error(err) process.exit(1) } // close your database connection and exit with success (0 code) // for example with mongoose mongoose.connection.close(function () { console.log('Mongoose connection disconnected') process.exit(0) }) }) })

关于代码process.on('SIGINT', ..如果我们使用命令node server.js或文件 index.js 运行/启动 Node.js API 会有所帮助。

这就是我们构建 Bash 脚本的原因,该脚本将“节点”作为启动项目 API 的命令。 可以将该 bash 脚本放在系统/服务器上的任何位置,除非并且直到 bash 脚本上给出的用于启动 API 主文件的路径正确。

最后,主 server.js/index.js 文件可能看起来像 -

 const express = require('express'); const bodyParser = require('body-parser'); // call body-parser here to parse body request from frontend var fileUpload = require('express-fileupload'); // call express-fileupload here to accept file in the form of multipart data from frontend // create express app const app = express(); // parse requests of content-type - application/json app.use(bodyParser.json({limit:'50mb'})); // here we try to set body request can accept requested data from frontend upto 50Mb // parse requests of content-type - application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: true,limit:'50mb' })); // here we try to set body request can accept requested data from frontend as urlencoded and upto 50Mb app.use(fileUpload()); // here enable app to use fileupload // Configuring the database const dbConfig = require('./config/database.config.js'); const mongoose = require('mongoose'); mongoose.Promise = global.Promise; const options = { auth: { user: "*********ww", password: "******dd" }, useNewUrlParser: true, useCreateIndex: true, useFindAndModify: false, autoIndex: true, // Don't build indexes reconnectTries: Number.MAX_VALUE, // Never stop trying to reconnect reconnectInterval: 500, // Reconnect every 500ms poolSize: 10, // Maintain up to 10 socket connections // If not connected, return errors immediately rather than waiting for reconnect bufferMaxEntries: 0, connectTimeoutMS: 10000, // Give up initial connection after 10 seconds socketTimeoutMS: 45000, // Close sockets after 45 seconds of inactivity family: 4, // Use IPv4, skip trying IPv6 serverSelectionTimeoutMS: 5000, // Timeout after 5s instead of 30s useUnifiedTopology: true }; mongoose.connect(dbConfig.url, options).then( () => { console.log("Successfully connected to the database"); }, err => { /** handle initial connection error */ console.log('Could not connect to the database. Exiting now...', err); process.exit(); } ); var port = process.env.PORT || 23804; // set our port and port must be enable on server var router = express.Router(); // call Router methode to enable api can accept multiple routes app.all('/*', function(req, res,next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Credentials", "true"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-Content-Type-Options, X-XSS-Protection, Content-Type, Accept, Key, Authorization"); res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, PATCH"); next() }); // define a simple route app.get('/', (req, res) => { res.json({"message": "Welcome to Dummy application. Sign Up and Login Quicky. Organize and keep track of all forms."}); }); // Require routes require('./app/routes/controlFile.routes.js')(app); const server = app.listen(port, () => console.log('Dummy-App API running on port ' + port)); var fs = require('fs'); var util = require('util'); var path = __dirname + `/mylogfiles/debug(${getDate()}).log`, printNextLine = false if(fs.existsSync(path)){ printNextLine = true } var log_file = fs.createWriteStream(path, {flags : 'a'}); /* 'a' : open the file for writing, positioning the stream at the end of the file. The file is created if not existing 'a+' : open the file for reading and writing, positioning the stream at the end of the file. The file is created if not existing 'r+' : open the file for reading and writing 'w+' : open the file for reading and writing, positioning the stream at the beginning of the file. The file is created if not existing (you can find more flags at https://nodejs.org/api/fs.html#fs_file_system_flags) */ if(printNextLine == true){ let prnt = '***************************************************************************************************************' log_file.write('\\n' + '\\n' + prnt + '\\n'); } var log_stdout = process.stdout; console.log = function(d) { // log_file.write((new Date).toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' }) + ' | ' + util.format(d) + '\\n'); log_stdout.write( util.format(d) + '\\n'); }; console.error = function(d) { // log_file.write((new Date).toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' }) + ' | ' + util.format(d) + '\\n'); log_stdout.write( util.format(d) + '\\n'); }; process.on('uncaughtException', function (err) { console.error(err) // console.error((new Date).toUTCString() + ' uncaughtException:', err.message) // console.error(err.stack) process.exit(1) }) process.on('SIGINT', () => { console.info('SIGINT signal received.') // Stops the server from accepting new connections and finishes existing connections. server.close(function(err) { // if error, log and exit with error (1 code) if (err) { console.error(err) process.exit(1) } // close your database connection and exit with success (0 code) // for example with mongoose mongoose.connection.close(function () { console.log('Mongoose connection disconnected') process.exit(0) }) }) }) function getDate(addDay){ let mydate = new Date() var month = mydate.getMonth() + 1; // month (in integer 0-11) var year = mydate.getFullYear(); // year var date = mydate.getDate() let h = mydate.getHours() let m = mydate.getMinutes() let s = mydate.getSeconds() // let desiredDate = `${year}.${month}.${date} H-${h} M-${m} S-${s}` let desiredDate = `${year}.${month}.${date}` return desiredDate }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM