如何避免重新启动NodeJS服务器时记录错误



我在监听8443的AWS虚拟机上使用NodeJS作为web服务器,并让它运行:

kill $(lsof -i :8443 | grep .node.bin | cut -d " " -f 2); cd $HOME/server; NODE_ENV=production npm start  >> stdout.txt 2>> stderr.txt &

我监视错误日志。每次我推送更改并重新启动服务器时,错误日志都会得到几行,例如:

/opt/bitnami/nodejs/bin/.node.bin[31215]:../src/node.cc:663:void node::ResetStdio((:断言"(0(==(err("失败。1:0x9ef190 node::Abort(([/opt/bitnami/nodejs/bin/.node.bin]2:0x9ef217[/opt/bitnami/nodejs/bin/.node.bin]3:0x9bd657 node::ResetStdio(([/opt/bitnami/nodejs/bin/.node.bin]4:0x9bd6c0 node::SignalExit(int([/opt/bitnami/nodejs/bin/.node.bin]5:0x7f7e4922a390[/lib/x86_64-linux-gnu/libphread.so.0]6:0x7f7e48f56ad3 epoll_wait[/lib/x86_64-linux-gnu/libc.so.6]7:0x13200b0[/opt/bitnami/nodjs/bin/.node.bin]8:0x130e26b uv_run[/opt/bitnami/nodejs/bin/.node.bin]9:0xa31ec3 node::NodeMainInstance::Run(([/opt/bitnami/nodejs/bin/.node.bin]10:0x9c1cc8 node::Start(int,char**([/opt/bitnami/nodejs/bin/.node.bin]11:0x7f7e48e6f840 __libc_start_main[/lib/x86_64-linux-gnu/libc.so.6]12:0x95c085[/opt/bitnami/nodjs/bin/.node.bin]中止(堆芯转储(npm ERR!代码ELIFECYCLEnpm ERR!错误号134npm ERR!EmotionAthletes@0.0.1开始:`node app.js`npm ERR!退出状态134npm ERR!npm ERR!在处失败EmotionAthletes@0.0.1启动脚本。npm ERR!这可能不是npm的问题。上面可能有额外的日志输出。npm ERR!此运行的完整日志可在以下位置找到:npm ERR/home/bitnami/.npm/\logs/2020-10-25T12_30_23_826Z-debug.lognpm[31199]:/src/node.cc:663:void node::ResetStdio((:断言"(0(==(err("失败。1:0x9ef190节点::Abort(([npm]2:0x9ef217[npm]3:0x9bd657节点::ResetStdio(([npm]4:0x7f7db55c4008[/lib/x86_64-linux-gnu/libc.so.6]5:0x7f7db55c4055[/lib/x86_64-linux-gnu/libc.so.6]6:0x994907[npm]7:0xbc9a29[npm]8:0xbcb817 v8::internal::Builtin_HandleApiCall(int,无符号长*,v8::internal::Isolate*([npm]9:0x13a72b9[npm]

如何让它在后台运行并避免记录重新启动错误?

我从NodeJS终止错误的差异中得到了答案:

const express = require('express');
const http = require('http');
const app = express();
const httpServer = http.createServer(app);
let server = httpServer.listen(8080);
process.on("SIGINT", () => {
  // Close main server and HTTP redirection server.
  server.close();
  mongoose.connection.close();
  console.log("SIGINT received, server stopped");
});

然后我可以用Control-C(^C(停止服务器而不会出错,或者重新启动它,让它在后台运行:

kill -s SIGINT $(lsof -i :8080 | grep .node.bin | cut -d " " -f 2); cd $HOME/server; cp config.prod.js config.js; NODE_ENV=production npm start  >> stdout.md 2>> stderr.md &

在生产中,服务器在8443上侦听SSL,我有一个小服务器,它将8080上的所有内容重定向到8443,所以我需要停止两个服务器,否则我无法重新启动,因为有一个端口正在使用:

let server, httpServer;
const https = require('https');
// SSL configuration
const credentials = {key: sslPrivateKey, cert: sslCertificate};
const httpsServer = https.createServer(credentials, app);
  
server = httpsServer.listen(8443);
// Also create a small server to redirect HTTP to HTTPS.
const http = express();
// Set up a route to redirect http to https.
http.get('*', function(req, res) {  
  res.redirect('https://' + req.headers.host + req.url);
});
// Have it listen on 8080.
httpServer = http.listen(8080);
process.on("SIGINT", () => {
  // Close main server and HTTP redirection server.
  server.close();
  httpServer.close();
  mongoose.connection.close();
  console.log("SIGINT received, server stopped");
});

为了安全起见,我使用端口8080和8443,因为1000以下的端口(80用于HTTP,443用于HTTPS(是保留端口。在大多数端口上侦听时,请参阅Node.js EACCES错误。因此,我没有给节点服务器root权限,而是运行这些shell命令将这些端口上的流量重定向到其他端口:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8443

最新更新