Est prise séquentielle des requêtes HTTP d'une opération de blocage dans le nœud?
Noter que les informations non pertinentes à ma question sera la 'cité'
comme (n'hésitez pas à passer ces).
Problème
Je suis l'aide d'un noeud à faire dans l'ordre les requêtes HTTP sur le compte de plusieurs clients. De cette façon, quelles en sont à l'origine de la client(e) s de différentes chargement de la page pour obtenir le résultat souhaité, maintenant, ne prend qu'une seule demande par l'intermédiaire de mon serveur. Je suis actuellement en utilisant le ‘async’ module pour le contrôle du débit et de la ‘demande’ module pour faire les requêtes HTTP. Il y a environ 5 rappels qui, à l'aide de la console.le temps, prend environ 2 secondes du début à la fin (de l'esquisse du code fourni ci-dessous).
Maintenant, je suis plutôt inexpérimenté avec le noeud, mais je suis conscient de l'
single-threaded nature de nœud. Alors que j'ai lu de nombreuses fois que le nœud
n'est pas intégrée au PROCESSEUR des tâches limitées, je ne comprenais pas vraiment ce que
signifiait jusqu'à maintenant. Si j'ai une bonne compréhension de ce qui se passe,
cela signifie que ce que j'ai actuellement (en développement) n'est en aucune façon
allez à l'échelle même de plus de 10 clients.
Question
Depuis que je ne suis pas un expert au niveau du nœud, je pose cette question (dans le titre) pour obtenir une confirmation que plusieurs séquentielle des requêtes HTTP est en effet de blocage.
Épilogue
Si c'est le cas, je m'attends je vais demander à un autre DONC, la question (après avoir fait les recherches appropriées) de discuter de diverses solutions possibles, devrais-je choisir de continuer d'aborder ce problème dans le nœud (qui lui-même peut ne pas être approprié pour ce que je suis en train de faire).
D'autres réflexions
Je suis vraiment désolé si cette question n'était pas assez détaillée, trop noobish, ou a en particulier un langage fleuri (je vais essayer d'être concis).
Grâce et de tous les upvotes à quelqu'un qui peut m'aider avec mon problème!
Le code que j'ai mentionnés plus tôt:
var async = require('async');
var request = require('request');
...
async.waterfall([
function(cb) {
console.time('1');
request(someUrl1, function(err, res, body) {
//load and parse the given web page.
//make a callback with data parsed from the web page
});
},
function(someParameters, cb) {
console.timeEnd('1');
console.time('2');
request({url: someUrl2, method: 'POST', form: {/* data */}}, function(err, res, body) {
//more computation
//make a callback with a session cookie given by the visited url
});
},
function(jar, cb) {
console.timeEnd('2');
console.time('3');
request({url: someUrl3, method: 'GET', jar: jar /* cookie from the previous callback */}, function(err, res, body) {
//do more parsing + computation
//make another callback with the results
});
},
function(moreParameters, cb) {
console.timeEnd('3');
console.time('4');
request({url: someUrl4, method: 'POST', jar: jar, form : {/*data*/}}, function(err, res, body) {
//make final callback after some more computation.
//This part takes about ~1s to complete
});
}
], function (err, result) {
console.timeEnd('4'); //
res.status(200).send();
});
Le blocage signifierait qu'aucun autre code, dans le même contexte d'exécution - pourrait être exécuté avant la demande. Dans cet exemple, le
request
appels retourner immédiatement et la suite des opérations peut être fait; d'où la non-bloquant. En attente sur une demande (comme cela peut être nécessaire) ne fait pas la request
de blocage d'appel.La "cascade" approche efficacement les causes de la sérialisation de la demande, mais ce n'est qu'un ordre imposé sur le sous-jacent async modèle et non-bloquant IO effectué par Node.js. Trivial contre-exemples incluent l'exécution de plusieurs chutes d'eau en parallèle, ou encore la manipulation de multiples simultanées Node.js les demandes.
Node.js utilisera "0 CPU" lors de l'exécution de l'OI web demande elle-même (le processus est si ridiculement IO). Si il y a en fait, est significative de traitement " (ie. dans un rappel), qui est une préoccupation distincte de combien de temps il faut pour aller chercher la ressource externe. Node.js calcul trivial est "limitée à un seul core/thread", qui est souvent assez vite, à moins d'utiliser un supplément de stratégie de concurrence d'accès telles que le traitement multiple.
Si c'est un problème que les calculs dans la demande de rappel sont la prise de 1 seconde (qui est en effet un long temps à bloquer le nœud"), puis de travailler sur le focus de la question et de l'exploration.
OriginalL'auteur youngrrrr | 2015-10-06
Vous devez vous connecter pour publier un commentaire.
Normalement, I/O dans node.js sont non-bloquant. Vous pouvez tester cela en faisant plusieurs demandes simultanément à votre serveur. Par exemple, si la demande prend 1 seconde, un blocage serveur serait de prendre 2 secondes à 2 demandes simultanées, mais un non-blocage du serveur serait de prendre un peu plus de 1 seconde pour traiter les demandes.
Cependant, vous pouvez délibérément faire des demandes de blocage à l'aide de la sync-demande module au lieu de demande. Évidemment, ce n'est pas recommandé pour les serveurs.
Voici un peu de code pour illustrer la différence entre le blocage et les non-blocage I/O:
L'exécution du code ci-dessus, vous verrez le non-blocage de test prend à peu près la même quantité de temps pour traiter toutes les demandes que pour une seule requête (par exemple, si vous définissez N = 10, la non-bloquante code s'exécute 10 fois plus rapide que le blocage de code). Cela illustre clairement que la demande est non-bloquant.
Réponse supplémentaire:
Vous avez également mentionné que vous êtes inquiet au sujet de votre processus de l'UC. Mais dans votre code, vous n'êtes pas d'analyse comparative de l'UC de l'utilitaire. Vous êtes à la mélangeant à la fois le réseau demande du temps (I/O, qui, nous le savons, est non-bloquant) et le PROCESSEUR de la durée des processus. Pour mesurer combien de temps la demande est en mode de blocage de changement de votre code:
Votre code bloque seulement dans le "plus de calcul" des pièces. De sorte que vous pouvez ignorer complètement le temps d'attente pour les autres parties à exécuter. En fait, c'est exactement la façon dont nœud peut servir à de multiples demandes simultanément. En attendant les autres parties à l'appel de l'respectives rappels (vous mentionner qu'il peut prendre jusqu'à 1 seconde) nœud peut exécuter du code javascript et poignée d'autres requêtes.
OriginalL'auteur slebetman
Votre code est non-bloquante car elle utilise non-blocage I/O avec le
request()
fonction. Cela signifie que node.js est libre de service à d'autres demandes, tandis que votre série de requêtes http est récupérée.Ce
async.waterfall()
t-il à l'ordre de vos demandes séquentielle et de transmettre les résultats de l'un à l'autre. Les demandes sont eux-mêmes non-bloquant etasync.waterfall()
ne pas les modifier ou de les influencer. La série que vous venez signifie que vous avez plusieurs non-blocage des demandes en ligne.Ce que vous avez est analogue à une série de imbriquée
setTimeout()
appels. Par exemple, cette séquence de code prend que 5 secondes pour obtenir à l'intérieur de rappel (comme votreasync.waterfall()
prend n secondes pour atteindre le dernier rappel):Mais, il utilise essentiellement à zéro du PROCESSEUR car il est à seulement 5 consécutifs opérations asynchrones. Le réel node.js le processus est engagé pour probablement pas plus de 1 ms à l'annexe de la prochaine
setTimeout()
et puis l'node.js processus littéralement pourrait faire beaucoup d'autres choses jusqu'à ce que le système enregistre un événement à déclencher la minuterie.Vous pouvez en savoir plus sur la façon dont le node.js file d'attente des événements travaille dans ces références:
Exécuter du Code Arbitraire lors de l'Attente Pour Rappel dans le Nœud?
code bloquant non-bloquant serveur http
Cachés fils en Javascript/Nœud qui n'a jamais exécuter le code de l'utilisateur: est-il possible, et si oui, pourrait-elle mener à une arcane possibilité pour un état de concurrence?
Comment JavaScript gérer les réponses AJAX dans le fond? (écrit sur le navigateur, mais le concept est le même)
Ce n'est pas une compréhension correcte. Un node.js le processus peut facilement avoir des milliers de non-blocage des demandes en vol en même temps. Votre séquentiellement temps mesuré n'est qu'un début à la fin du temps - il n'a rien à voir avec les ressources de l'UC ou d'autres OS de ressources consommées (voir les commentaires ci-dessous sur la non-blocage de la consommation de ressources).
Non-blocage I/O consomme presque pas de CPU (un peu seulement lorsque la demande est envoyée à l'origine, puis un peu quand la suite arrive), mais alors que le compmuter est en attente pour la suppression de résultat, pas de CPU est consommé à tous et aucun OS thread est consommé. C'est une des raisons qui node.js les échelles de bien pour les non-blocage I/O pas de ressources sont utilisés lorsque l'ordinateur est en attente d'une réponse de supprimer le site.
Si votre traitement de la demande est gourmand en ressources (par exemple, prend une quantité mesurable de pure blocage du PROCESSEUR de temps à traiter), alors oui, vous voulez explorer d'obtenir de multiples processus impliqués dans l'exécution de calculs. Il y a plusieurs façons de le faire. Vous pouvez utiliser le clustering (vous n'avez qu'à de multiples identiques node.js les processus de chaque travail sur les demandes de clients différents) avec les nodejs clustering module. Ou, vous pouvez créer une file d'attente de tâches de calcul intensif de travail à faire et un ensemble de processus enfants qui ne le calcul intensif travail. Ou, il ya plusieurs autres options aussi. Cela n'est pas le type de problème que l'on a besoin pour passer à partir de node.js pour résoudre ce problème - il peut être résolu à l'aide de node.js l'amende juste.
Et de plus, grâce pour résoudre mon commenté préoccupations et +1 pour la mention de clustering comme une solution possible, tout en utilisant le nœud!
OriginalL'auteur jfriend00
Vous pouvez utiliser la file d'attente de processus simultanés http appels en nodeJs
https://www.npmjs.com/package/concurrent-queue
Rappelez-vous qu'il doit mettre en œuvre pour les sensibles, les appels d'entreprise où la ressource qui doit être accessible ou mise à jour à un moment par un seul utilisateur.
Cela va bloquer votre I/O et de faire vos utilisateurs à attendre et le temps de réponse sera lente.
Optimisation:
Vous pouvez le faire plus rapidement et d'optimiser la création de ressources dépendant de la file d'attente. Afin qu'il y ait une file d'attente séparée pour chaque ressource partagée et synchrone appels pour une même ressource ne peut être exécutée que pour une même ressource pour les différentes ressources les appels seront exécutées de manière asynchrone
Supposons que vous souhaitez mettre en œuvre que sur la base de l'utilisateur actuel. De sorte que, pour le même utilisateur http appels ne peuvent exécuter de façon synchrone et pour les différents utilisateurs https appels seront asynchrone
Ce sera rapide et bloc d'e/S que pour la ressource pour laquelle vous souhaitez.
OriginalL'auteur Ibtesam Latif