gpt4 book ai didi

Node.js:自动重启没有响应的 Node 服务器的好方法是什么?

转载 作者:搜寻专家 更新时间:2023-10-31 23:01:51 24 4
gpt4 key购买 nike

我继承了一个有点乱的 node.js/Express 应用程序。在重新启动之前,它会定期且相当随机地卡住并且不响应任何请求。

我怀疑应用程序中的某些东西正在阻塞,要么陷入循环,要么在没有使用适当的异步技术的情况下向外部 api 发出请求,并且永远不会得到响应,也永远不会在女巫点超时,服务器只是停止响应但不会崩溃。

我显然想找到罪魁祸首代码并解决问题,但与此同时我想找到一种在服务器停止响应时自动重启服务器的方法。

为了在本地测试解决方案(因为我目前不知道真正的罪魁祸首),我创建了以下 Express 路线,它模拟了我得到的确切行为。

app.get('/block-block-block', function (req, res){ 
for(;;) {}
};

我的问题是上面的路由被命中(这会立即停止服务器响应任何东西),有没有办法在内部检测 Node 中的阻塞并重新启动或关闭?如果不是,什么是检查服务器何时没有响应并重新启动它的好解决方案?

我所做的大多数搜索都会让我找到像 forever 这样的工具和 PM2 .如果您的应用程序崩溃,这些方法会很好用,但我真的看不到任何在应用程序随机阻塞时重新启动的功能。

最佳答案

我想出了如何使用原生 Node 功能解决这个问题。 Migg 的回答很好,引导我朝着正确的方向前进,但它仍然没有说明如何在事件循环完全阻塞时自动重启。

诀窍是使用 Node 的原生 child_process模块和 fork method从另一个 Node 实例启动服务器并让该实例 ping 服务器以获取响应,并在卡住时重新启动它。这类似于 Forever 和 PM2 的工作方式。很难相信没有一种简单的方法可以使用这些库中的任何一个来实现它,但这是您可以天真地做到的方式。

我已经对这段代码进行了大量评论,以指出每件事都在做什么。另请注意,我使用的是 ES2015 的 Arrow Functions.如果您不熟悉,请去阅读它们。

var fork = require('child_process').fork;
var server, heartbeat;

function startServer () {
console.log('Starting server');
server = fork('server');

//when the server goes down restart it
server.on('close', (code) => {
startServer();
});

//when server sends a heartbeat message save it
server.on('message', (message) => {
heartbeat = message ? message.heartbeat : null;
});

//ask the server for a heartbeat
server.send({request: 'heartbeat'});

//wait 5 seconds and check if the server responded
setTimeout(checkHeartbeat, 5000);
}

function checkHeartbeat() {
if(heartbeat) {
console.log('Server is alive');

//clear the heart beat and send request for a new one
heartbeat = null;
server.send({request: 'heartbeat'});

//set another hearbeat check
setTimeout(checkHeartbeat, 5000);

} else {
console.log('Server looks stuck...killing');
server.kill();
}
}

startServer();

请务必将 server.js 更改为您要运行的任何 Node 应用程序。

现在在您的服务器上添加以下内容以响应心跳请求。

//listen and respond to heartbeat request from parent
process.on('message', (message) => {
if(message && message.request === 'heartbeat') {
process.send({heartbeat: 'thump'});
}
});

最后添加一个超时来测试它是否有效(不适用于生产!)

//block the even loop after 30 seconds 
setTimeout(() => {
for(;;){}
}, 30000);

关于Node.js:自动重启没有响应的 Node 服务器的好方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35185522/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com