Comment puis-je arrêter une Node.js http(s) serveur immédiatement?
J'ai un Node.js application qui contient une adresse http(s) serveur.
Dans un cas précis, j'ai besoin de l'arrêt de ce serveur par programmation. Ce que je suis en train de faire est d'appeler ses close()
fonction, mais cela n'aide pas, car elle attend tout gardé en vie connexions de finir premier.
Donc, fondamentalement, ce arrêts le serveur, mais seulement après un temps d'attente minimal de 120 secondes. Mais je veux que le serveur à l'arrêt immédiatement - même si cela implique de rompre avec actuellement traitées les demandes.
Ce que je ne peux pas faire, c'est un simple
process.exit();
que le serveur n'est qu'une partie de l'application, et le reste de l'application doit rester en cours d'exécution. Ce que je cherche, c'est quelque chose de conceptuellement comme server.destroy();
ou quelque chose comme ça.
Comment pourrais-je y parvenir?
PS: Le délai persistant pour les connexions est habituellement exigé, il n'est donc pas une option viable pour diminuer ce temps.
- Il y a un problème de ce nœud: github.com/nodejs/node/issues/2642
Vous devez vous connecter pour publier un commentaire.
Le truc, c'est que vous devez vous abonner au serveur
connection
événement qui vous donne le support de la nouvelle connexion. Vous devez vous rappeler ce socket et plus tard, directement après l'avoir appeléserver.close()
, de détruire les socket en utilisantsocket.destroy()
.En outre, vous avez besoin d'écouter le socket
close
événement pour le retirer de la pile si elle part naturellement en raison de son délai persistant en manque.J'ai écrit un petit exemple d'application que vous pouvez utiliser pour illustrer ce comportement:
Fondamentalement, ce qu'il fait est de commencer un nouveau serveur HTTP, décompte de 10 à 0, et fermer le serveur au bout de 10 secondes. Si aucune connexion n'a été établie, le serveur s'arrête immédiatement.
Si une connexion a été établie, et il est encore ouvert, il est détruit.
Si il était déjà mort naturellement, seul un message est imprimé à ce point dans le temps.
socket.on("close",...)
êtresocket.once("close",...)
?sockets
variable pourrait utiliserSet
commeconst sockets = new Set(); sockets.add(socket); sockets.forEach((socket) => socket.destroy());
.J'ai trouvé un moyen de le faire sans avoir à garder une trace des connexions ou d'avoir à les forcer fermé. Je ne suis pas sûr de la façon fiable, il est à travers le Nœud de versions ou si il y a des conséquences négatives pour cela, mais il semble que cela fonctionne parfaitement bien pour ce que je suis en train de faire. L'astuce consiste à émettre de la "proximité" de l'événement à l'aide de
setImmediate
juste après l'appel de laclose
méthode. Cela fonctionne comme suit:Au moins pour moi, cela finit par libérer le port afin que je puisse commencer une nouvelle HTTP(S) de service par le temps, la fonction de rappel est appelée (qui est à peu près instantanément). Les connexions existantes restent ouverts. Je suis en utilisant ce pour redémarrer automatiquement le service HTTPS après le renouvellement d'un Let's Encrypt certificat.
server.close(); setImmediate(callback);
.server.close()
et en ouvrir un nouveau dans la fonction de rappel vous permettra de conserver les connexions existantes, tandis que d'écouter les nouvelles. Votre exemple de code semble louche... vous ne devriez pas avoir à émettre des événements sur le serveur, donc je suis curieux de savoir comment vous en êtes arrivé à cette conclusion.Si vous avez besoin de garder un processus vivant, après la fermeture du serveur, puis Golo Roden la solution est probablement la meilleure.
Mais si vous êtes à la fermeture du serveur dans le cadre d'un arrêt normal de la procédure, vous avez juste besoin de ceci:
Fondamentalement, les prises que votre serveur utilise ne garde que le processus en vie alors qu'ils sont effectivement un service à la demande. Alors qu'ils sont juste assis là sans rien faire (à cause d'une connexion persistante), un appel à
server.close()
va clore le processus, tant qu'il n'y a rien d'autre en gardant le processus vivant. Si vous avez besoin de faire d'autres choses après que le serveur ferme, dans le cadre de votre arrêt normal, vous pouvez brancher dansprocess.on('beforeExit', callback)
pour terminer votre gracieuse arrêt des procédures.v7.10.0
et d'Exprimer4.15.2
. Avez-vous testé?La https://github.com/isaacs/server-destroy bibliothèque fournit un moyen facile de
destroy()
un serveur avec le comportement désiré dans la question (par le suivi de connexions ouvertes et de détruire chacun d'eux sur le serveur détruire, comme décrit dans les autres réponses).Comme d'autres l'ont dit, la solution est de garder une trace de tous les sockets et les fermer manuellement. Mon noeud package tuables peut le faire pour vous. Un exemple (à l'aide d'exprimer, mais vous pouvez l'appeler utilisation tuables sur toute
http.server
exemple):Encore un autre nodejs package pour effectuer un arrêt de la suppression des connexions: http-arrêt, qui semble raisonnablement maintenu au moment de la rédaction (Sept. 2016) et a fonctionné pour moi sur NodeJS 6.x
À partir de la documentation
Utilisation
Il existe actuellement deux façons d'utiliser cette bibliothèque. La première est explicite l'emballage de l'objet Serveur:
La deuxième est implicitement l'ajout de prototype de la fonctionnalité de l'objet Serveur:
Ma meilleure supposition serait de tuer les connexions manuellement (c'est à dire à force de près c'est sockets).
Idéalement, cela devrait être fait en creusant le serveur lui-même et de fermeture de sockets par la main. Alternativement, on peut exécuter une commande shell qui fait la même (à condition que le serveur a les privilèges adéquats &c.)
Express
, par exemple) et quelle version de Nœud.js/bibliothèques que vous utilisez (API varier au fil du temps)JS:
processus.exit(code); //code à 0 pour la réussite et 1 pour échouer
process.exit()
n'est pas une option.