Node.js 앱을 올바르게 종료
17611 단어 nodejavascripttutorialbeginners
요청을 잘 처리하고 새 요청을 수락하지 않도록 하려면 앱을 올바르게 종료하는 것이 중요합니다. 웹 서버를 예로 들어 보겠습니다.
const http = require('http');
const server = http.createServer(function (req, res) {
setTimeout(function () {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}, 4000);
}).listen(9090, function (err) {
console.log('listening http://localhost:9090/');
console.log('pid is ' + process.pid);
});
보시다시피 서버가 제대로 종료되지 않고 처리 요청이 올바른 응답을 받지 못합니다. 먼저 문제를 해결하기 위해 노드 프로세스가 어떻게 종료되는지 이해해야 합니다.
프로세스는 종료되려고 할 때 신호를 받습니다. 그들은 다른 종류의 signals입니다. 특히 다음 세 가지에 초점을 맞출 것입니다.
Node.js는 프로세스가 신호를 받으면 이벤트를 발생시킵니다. 이러한 이벤트에 대한 핸들러를 작성할 수 있습니다. 이 경우 보류 중인 요청을 처리하고 새 요청을 받지 않도록 서버를 닫습니다.
// ...
function handleExit(signal) {
console.log(`Received ${signal}. Close my server properly.`)
server.close(function () {
process.exit(0);
});
}
process.on('SIGINT', handleExit);
process.on('SIGQUIT', handleExit);
process.on('SIGTERM', handleExit);
이제 우리 서버는 요청을 잘 처리하고 올바르게 종료합니다. 의 nice article에서 자세한 내용을 읽을 수 있습니다. 데이터베이스가 있는 서버를 올바르게 종료하는 방법에 대해 자세히 설명합니다.
또한 death(만든 JP Richardson)이라는 이 논리를 처리하는 노드 모듈도 있습니다.
const ON_DEATH = require('death')
ON_DEATH(function(signal, err) {
// clean up code here
})
때로는 충분하지 않습니다
최근에 제대로 종료하기 위해 서버가 새로운 요청을 수락해야 하는 상황에 직면했습니다. 몇 가지 설명을 드리겠습니다. 내 서버가 웹후크를 구독했습니다. 이 웹후크는 구독 할당량이 제한되어 있습니다. 따라서 이 할당량을 초과하지 않으려면 서버 종료 시 제대로 구독을 취소해야 합니다. 구독 취소 워크플로는 다음과 같습니다.
이벤트 루프가 비어 있으면 Node.js 프로세스가 자동으로 닫힙니다. 1.과 2. 사이에서 볼 수 있듯이 이벤트 루프가 비어 있으므로 프로세스가 종료되고 성공적으로 구독을 취소할 수 없습니다.
다음은 우리가 사용할 새 서버 코드베이스입니다.
const server = http.createServer(function (req, res) {
const params = qs.decode(req.url.split("?")[1]);
if (params.mode) {
res.writeHead(200);
res.write(params.challenge);
res.end();
} else {
let body = "";
req.on("data", chunk => {
body += chunk;
});
req.on("end", () => {
console.log('event', JSON.parse(body))
res.writeHead(200);
res.end();
});
}
}).listen(9090, function (err) {
console.log('listening http://localhost:9090/');
console.log('pid is ' + process.pid);
fetch('http://localhost:3000/webhook?mode=subscribe&callback=http://localhost:9090')
});
두 가지 변경 사항이 있습니다. 서버가 포트 9090에서 수신을 시작하면 서버를 웹후크에 구독하라는 첫 번째 요청을 보냅니다.
// ...
fetch('http://localhost:3000/webhook?mode=subscribe&callback=http://localhost:9090')
// ...
또한
challenge
라는 토큰으로 응답하여 웹후크 구독을 확인할 수 있도록 서버의 요청 핸들러를 변경했습니다.// ...
if (params.mode) {
res.writeHead(200);
res.write(params.challenge);
res.end();
} else {
// ...
}
// ...
웹후크에 요청을 보내도록
handleExit
함수의 구현을 변경해 보겠습니다. webhook에 서버 구독을 취소하도록 요청합니다.function handleExit(signal) {
console.log(`Received ${signal}. Close my server properly.`)
fetch('http://localhost:3000/webhook?mode=unsubscribe&callback=http://localhost:9090')
}
웹후크가 구독 취소를 확인할 때 서버 프로세스를 종료하라는 챌린지로 응답하는 코드를 업데이트해야 합니다.
// ...
if (params.mode) {
res.writeHead(200);
res.write(params.challenge);
res.end();
if (params.mode === 'unsubscribe') {
server.close(function () {
process.exit(0);
});
}
} else {
// ...
}
// ...
웹후크가 구독 취소를 확인하면 서버를 닫아 새 요청을 받지 않고 프로세스를 올바르게 종료합니다. 이것이 Twitch API webhook 구독/구독 취소가 작동하는 방식입니다.
서버를 종료하려고 할 때 서버가 어떻게 작동하는지 봅시다. 좀 더 시각적으로 보이도록 몇 가지 로그를 추가했습니다.
보시다시피 제대로 종료되지 않습니다. 구독 취소를 확인하는 웹후크 요청을 받기 전에 서버의 프로세스가 종료됩니다. 따라서 webhook은 계속해서 이벤트를 서버로 보냅니다.
이 문제를 해결하려면 Node.js 프로세스가 종료되지 않도록 해야 합니다. 프로세스를 일시 중지하고 exiting on
process.stdin.resume
과 같은 비활성화 기본 동작을 재정의하는 메서드Ctrl+C
를 사용할 수 있습니다.const http = require('http');
process.stdin.resume();
// ...
그리고 지금?
이제 프로세스를 종료하기 전에 확인을 기다립니다.
이 기사에 제시된 모든 소스로 repository을 만들었습니다.
도움이 되길 바랍니다 🙌
피드백 감사합니다 🙏 질문이 있으시면 저에게 트윗해주세요!
Reference
이 문제에 관하여(Node.js 앱을 올바르게 종료), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/yvonnickfrin/shutdown-correctly-node-js-app-39jc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)