在 windows 平台上 PM2 不支持 Node.js for "Graceful Shutdown"
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 文件并行。
现在,"Graceful Shutdown"还剩下什么:-
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)
})
})
})
如果我们 run/start Node.js API 使用命令,关于代码 process.on('SIGINT', ..
将有所帮助
node server.js
或文件 index.js 已命名。
这就是我们构建 Bash 脚本的原因,该脚本将 'node' 作为启动项目的命令-API。
可以将 bash 脚本放在 system/server 的任何位置,除非并直到 bash 脚本上给出的用于启动 API 主文件的路径是正确的。
最后,主服务器.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
}
我试过这种方法-
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
}
现在,"Graceful Shutdown"还剩下什么:-
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)
})
})
})
如果我们 run/start Node.js API 使用命令,关于代码 process.on('SIGINT', ..
将有所帮助
node server.js
或文件 index.js 已命名。
这就是我们构建 Bash 脚本的原因,该脚本将 'node' 作为启动项目的命令-API。 可以将 bash 脚本放在 system/server 的任何位置,除非并直到 bash 脚本上给出的用于启动 API 主文件的路径是正确的。
最后,主服务器.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
}