J'ai récemment découvert le monitoring nodejs. Même si je n'ai pas l'énergie d'apprendre à écrire une version simple du monitoring, je ne peux toujours pas m'empêcher d'apprendre comment obtenir ces indicateurs (après avoir consulté beaucoup d'informations, j'ai l'impression) qu'il y a trop peu d'introduction à ce contenu sur l'Internet domestique. Je suis également en train de trier les points de connaissance des nœuds de serveur, je vais donc les résumer dans cet article et les partager avec vous).
Il peut y avoir des problèmes avec certains des indicateurs de cet article. Bienvenue dans l'échange. En fait, vous pouvez organiser ces données et les écrire dans une bibliothèque de surveillance et les utiliser dans vos propres projets de petite et moyenne taille. Ensuite, le front-end React dispose d'outils tels que bizcharts et g2, et le front-end dessine lui-même le grand écran de données. Je pense que les dimensions des données collectées par esay Monitor ne sont pas aussi complètes que les nôtres.
Les goulots d'étranglement des performances des serveurs sont généralement les suivants :
d'utilisation et de charge du processeur, qui peuvent tous deux refléter dans une certaine mesure l'activité d'une machine.
L'utilisation du processeur correspond aux ressources du processeur occupées par les programmes en cours d'exécution, indiquant comment la machine exécute les programmes à un moment donné. Plus le taux d'utilisation est élevé, cela signifie que la machine exécute actuellement de nombreux programmes, et vice versa. Le niveau d'utilisation est directement lié à la puissance du processeur. Commençons par comprendre les API pertinentes et quelques explications terminologiques pour nous aider à comprendre le code permettant d'obtenir l'utilisation du processeur.
os.cpus()
renvoie un tableau d'objets contenant des informations sur chaque cœur logique du processeur.
model : une chaîne spécifiant le modèle du cœur du CPU.
speed : nombre spécifiant la vitesse du cœur du processeur en MHz.
times : Un objet contenant les propriétés suivantes :
REMARQUE : la nice
valeur concerne uniquement POSIX. Sur les systèmes d'exploitation Windows, la valeur de nice
est toujours 0 pour tous les processeurs.
Lorsque vous voyez l'utilisateur et les champs sympas, certains étudiants sont confus quant aux avantages, et moi aussi, alors je me suis soigneusement renseigné sur leur signification, veuillez continuer.
user indique la proportion de temps pendant laquelle le processeur fonctionne en mode utilisateur .
L'exécution du processus d'application est divisée en mode utilisateur et mode noyau : le CPU exécute la propre logique de code du processus d'application en mode utilisateur, généralement des calculs logiques ou numériques ; le CPU exécute les appels système lancés par le processus en mode noyau, généralement en réponse ; à la demande de ressources du processus.
Un programme en espace utilisateur est tout processus qui ne fait pas partie du noyau. Les shells, les compilateurs, les bases de données, les serveurs Web et les programmes liés au bureau sont tous des processus de l'espace utilisateur. Si le processeur n'est pas inactif, il est normal que la majeure partie du temps CPU soit consacrée à l'exécution de processus de l'espace utilisateur.
Nice représente la proportion de temps pendant lequel le CPU fonctionne en mode utilisateur à faible priorité .Une faible priorité signifie que la valeur nice du processus est inférieure à 0.
L'utilisateurreprésente la proportion de temps pendant lequel le processeur fonctionne en mode noyau .
De manière générale, l'utilisation du processeur en mode noyau ne doit pas être trop élevée, sauf si le processus d'application lance un grand nombre d'appels système. S'il est trop élevé, cela signifie que l'appel système prend beaucoup de temps, comme des opérations d'E/S fréquentes.
inactifindique la proportion de temps pendant laquelle le processeur est en état d'inactivité, pendant lequel le processeur n'a aucune tâche à effectuer.
irq représente la proportion de temps pendant laquelle le processeur gère les interruptions matérielles .
L'interruption de la carte réseau est un exemple typique : une fois que la carte réseau a reçu le paquet de données, elle informe le processeur du traitement via une interruption matérielle. Si le trafic réseau du système est très important, une augmentation significative de l'utilisation de l'irq peut être observée.
si l'état de l'utilisateur est inférieur à 70 %, l'état du noyau est inférieur à 35 % et l'état global est inférieur à 70 %, cela peut être considéré comme un état sain.
L'exemple suivant illustre l'utilisation de la méthode os.cpus() dans Node.js :
Exemple 1 :
// Programme Node.js pour démontrer le //Méthode os.cpus() // Allocation du module OS const os = exiger('os'); // Impression des valeurs os.cpus() console.log(os.cpus());
Sortie :
[ modèle : 'CPU Intel(R) Core(TM) i5-7200U à 2,50 GHz', vitesse: 2712, fois: {utilisateur :900000, nice :0, sys:940265, inactif :11928546, irq :147046 } }, { modèle : 'CPU Intel(R) Core(TM) i5-7200U à 2,50 GHz', vitesse: 2712, fois: {utilisateur :860875, nice :0, sys:507093, inactif :12400500, irq:27062 } }, { modèle : 'CPU Intel(R) Core(TM) i5-7200U à 2,50 GHz', vitesse: 2712, fois: {utilisateur :1273421, nice :0, sys:618765, inactif :11876281, irq :13125 } }, { modèle : 'CPU Intel(R) Core(TM) i5-7200U à 2,50 GHz', vitesse: 2712, fois: { user:943921, nice:0, sys:460109, ralenti:12364453, irq:12437 } } ]
Voici le code permettant d'obtenir l'utilisation du processeur
const os = require('os'); const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); classe OSUtils { constructeur() { this.cpuUsageMSDefault = 1000 ; //Période par défaut d'utilisation du CPU} /** * Obtenez l'utilisation du processeur pendant une certaine période de temps* @param { Number } Options.ms [Période de temps, la valeur par défaut est de 1 000 ms, soit 1 seconde] * @param { Boolean } Options.percentage [true (renvoyé sous forme de pourcentage) false] * @returns {Promesse} */ async getCPUUsage(options={}) { const ça = ceci; let { cpuUsageMS, pourcentage } = options ; cpuUsageMS = cpuUsageMS || that.cpuUsageMSDefault; const t1 = that._getCPUInfo(); // Les informations sur le processeur au moment t1 attendent sleep(cpuUsageMS); const t2 = that._getCPUInfo(); // Informations sur le processeur au moment t2 const ralenti = t2.idle - t1.idle; const total = t2.total - t1.total ; soit utilisation = 1 - inactif / total ; si (pourcentage) utilisation = (utilisation * 100,0).toFixed(2) + "%" ; utilisation de retour ; } /** * Obtenir des informations sur le temps instantané du processeur * @returns { Object } Informations sur le processeur * utilisateur <numéro> Le nombre de millisecondes passées par le processeur en mode utilisateur. * nice <numéro> Le nombre de millisecondes que le CPU passe en mode nice. * sys <numéro> Nombre de millisecondes passées par le processeur en mode système. * Idle <numéro> Le nombre de millisecondes passées par le processeur en mode inactif. * irq <numéro> Le nombre de millisecondes passées par le processeur en mode de demande d'interruption. */ _getCPUInfo() { const cpus = os.cpus(); laissez user = 0, nice = 0, sys = 0, ralenti = 0, irq = 0, total = 0 ; pour (laisser le processeur dans le processeur) { const fois = cpus[cpu].times; utilisateur += fois.utilisateur; sympa += fois.nice; sys += times.sys; ralenti += fois.idle; irq += fois.irq; } total += utilisateur + sympa + sys + inactif + irq ; retour { utilisateur, système, inactif, total, } } } const cpuUsage = new OSUtils().getCPUUsage({ pourcentage : true }); console.log('cpuUsage: ', cpuUsage.then(data=>console.log(data))); // Mon ordinateur a 6,15%
.La charge CPU (loadavg) est facile à comprendre et fait référence à un certain. période de temps.Le nombre de processus occupant du temps CPU et de processus en attente de temps CPU est la charge moyenne. Les processus en attente de temps CPU font ici référence aux processus en attente d'être réveillés, à l'exclusion des processus en état d'attente.
Avant cela, nous devons apprendre une API de nœud
os.loadavg()
qui renvoie un tableau contenant une charge moyenne de 1, 5 et 15 minutes.
La charge moyenne est une mesure de l'activité du système calculée par le système d'exploitation et exprimée sous forme décimale.
La moyenne de charge est un concept spécifique à Unix. Sous Windows, la valeur de retour est toujours [0, 0, 0]
Elle est utilisée pour décrire l'activité actuelle du système d'exploitation. Elle peut être simplement comprise comme le nombre moyen de tâches que le processeur utilise et attend d'utiliser le système d'exploitation. CPU par unité de temps. La charge du processeur est trop élevée, ce qui indique qu'il y a trop de processus dans Node, cela peut se traduire par le démarrage répété de nouveaux processus à l'aide du module Forbidden City.
const os = exiger('os'); //Nombre de threads CPU const length = os.cpus().length; //La charge moyenne d'un processeur monocœur renvoie un tableau contenant la charge moyenne de 1, 5 et 15 minutes os.loadavg().map(load => load / length
Expliquons d'abord une API
);, sinon vous ne pouvez pas le lire Comprendre notre code pour obtenir les indicateurs de mémoire,
Cette fonction renvoie 4 paramètres, les significations et différences sont les suivantes :
Utilisez le code suivant pour imprimer l'utilisation de la mémoire d'un processus enfant. On peut voir que rss est à peu près égal au RES de la commande top. De plus, la mémoire du processus principal n'est que de 33 Mo, ce qui est plus petit que la mémoire du processus enfant. On peut voir que leur utilisation de la mémoire est calculée indépendamment.
var showMem = fonction(){ var mem = process.memoryUsage(); var format = fonction (octets){ return (octets / 1024/1024).toFixed(2) + 'Mo'; } ; console.log('Processus : heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss) + ' externe :' + format (mem.external) ); console.log('---------------------------------------------- --- ---------------'); };
Pour Node, une fois qu'une fuite de mémoire se produit, il n'est pas si facile de la dépanner. S'il est surveillé que la mémoire augmente seulement mais ne diminue pas, il doit y avoir un problème de fuite de mémoire. Une utilisation saine de la mémoire devrait augmenter et diminuer. Lorsque l'accès est important, il augmente, et lorsque l'accès diminue, il diminue.
const os = require('os'); // Vérifiez l'utilisation actuelle de la mémoire du processus Node const { rss, heapUsed, heapTotal } = process.memoryUsage(); // Récupère la mémoire libre du système const systemFree = os.freemem(); // Récupère la mémoire système totale const systemTotal = os.totalmem(); module.exports = { mémoire : () => { retour { system : 1 - systemFree / systemTotal, // Tas d'utilisation de la mémoire système : heapUsed / headTotal, // Noeud d'utilisation de la mémoire du processus du nœud actuel : rss / systemTotal, // Taux d'utilisation de la mémoire du processus du nœud actuel de la mémoire système} } }
La surveillance des disques surveille principalement l'utilisation du disque. En raison de l'écriture fréquente des journaux, l'espace disque est progressivement utilisé. Une fois que le disque ne suffit pas, cela entraînera divers problèmes dans le système. Définissez une limite supérieure pour l'utilisation du disque. Une fois que l'utilisation du disque dépasse la valeur d'avertissement, l'administrateur du serveur doit organiser les journaux ou nettoyer le disque.
Le code suivant fait référence à easy Monitor 3.0.
const { execSync } = require('child_process'); résultat const = execSync('df -P', { encodage : 'utf8'}) lignes const = result.split('n'); const métrique = {} ; lignes.forEach(ligne => { if (line.startsWith('/')) { const match = line.match(/(d+)%s+(/.*$)/); si (correspondance) { taux const = parseInt(match[1] || 0); const monté = match[2]; if (!Mounted.startsWith('/Volumes/') && !Mounted.startsWith('/private/')) { métrique[montée] = taux ; } } } }); console.log(metric)
La charge d'E/S fait principalement référence aux E/S du disque. Cela reflète la situation de lecture et d'écriture sur le disque. Pour les applications écrites par Node, qui sont principalement destinées aux services réseau, il est peu probable que la charge d'E/S soit trop élevée. La pression d'E/S de nombreuses lectures provient de la base de données. .
Pour obtenir les indicateurs d'E/S, nous devons comprendre une commande Linux appelée iostat. Si elle n'est pas installée, vous devez l'installer. Voyons pourquoi cette commande peut refléter les indicateurs d'E/S
iostat -dx.
Description de la propriété
rrqm/s : nombre d'opérations de lecture de fusion par seconde. Autrement dit, rmerge/s (le nombre de fois où les requêtes de lecture adressées au périphérique sont fusionnées par seconde et le système de fichiers fusionnera les requêtes pour lire le même bloc) wrqm/s : nombre d'opérations d'écriture de fusion par seconde. Autrement dit, wmerge/s (le nombre de fois où les demandes d'écriture sur le périphérique sont fusionnées par seconde) r/s : nombre de lectures effectuées à partir du périphérique d'E/S par seconde. C'est rio/s w/s : nombre d'écritures sur le périphérique d'E/S effectuées par seconde. C'est wio/s rsec/s : Nombre de secteurs lus par seconde. C'est résect/s wsec/s : Nombre de secteurs écrits par seconde. c'est-à-dire wsect/s rkB/s : K octets lus par seconde. C'est la moitié de rsect/s car la taille de chaque secteur est de 512 octets. wkB/s : nombre de K octets écrits par seconde. C'est la moitié de wsect/s. avgrq-sz : taille moyenne des données (secteurs) par opération d'E/S de périphérique. avgqu-sz : longueur moyenne de la file d'attente d'E/S. wait : temps d'attente moyen (en millisecondes) pour chaque opération d'E/S de périphérique. svctm : temps de traitement moyen (en millisecondes) de chaque opération d'E/S de périphérique. %util : quel pourcentage d'une seconde est utilisé pour les opérations d'E/S, c'est-à-dire le pourcentage de CPU consommé par les E/S.
Nous devons uniquement surveiller %util.
Si %util est proche de 100 % , cela signifie qu'il y a trop d'I. Des requêtes /O sont générées. Le système d'E/S est entièrement chargé et il peut y avoir un goulot d'étranglement sur ce disque.
Si wait est beaucoup plus long que svctm, cela signifie que la file d'attente d'E/S est trop longue et que le temps de réponse de l'application devient plus lent. Si le temps de réponse dépasse la plage tolérée par l'utilisateur, vous pouvez envisager de remplacer un disque plus rapide. ajuster l'algorithme d'ascenseur du noyau et optimiser l'application, ou mettre à niveau le processeur.
surveille le temps de réponse des pages de Nodejs. La solution est sélectionnée dans l'article de blog de l'enseignant Liao Xuefeng.
Récemment, je souhaite surveiller les performances de Nodejs. L'enregistrement et l'analyse du journal sont trop fastidieux. Le moyen le plus simple consiste à enregistrer le temps de traitement de chaque requête HTTP et à le renvoyer directement dans l'en-tête de réponse HTTP.
Enregistrer l'heure d'une requête HTTP est très simple. Cela signifie enregistrer un horodatage lors de la réception de la requête et enregistrer un autre horodatage lors de la réponse à la requête. La différence entre les deux horodatages est le temps de traitement.
Cependant, le code res.send() est réparti sur différents fichiers js, vous ne pouvez donc pas modifier chaque fonction de traitement d'URL.
La bonne idée est d’utiliser un middleware pour y parvenir. Mais Nodejs n'a aucune méthode pour intercepter res.send(), comment le casser ?
En fait, tant que nous changeons légèrement notre façon de penser, abandonnons la méthode POO traditionnelle et considérons res.send() comme un objet fonction, nous pouvons d'abord enregistrer la fonction de traitement d'origine res.send, puis remplacer res.send par notre propre fonction de traitement :
app.use (function (req, res, next) { //Heure de début de l'enregistrement : var exec_start_at = Date.now(); //Enregistrez la fonction de traitement d'origine : var _send = res.send; // Lier notre propre fonction de gestionnaire : res.envoyer = fonction () { //Envoyer l'en-tête : res.set('X-Execution-Time', String(Date.now() - exec_start_at)); // Appel de la fonction de traitement d'origine : return _send.apply(res, arguments); } ; suivant(); });
En quelques lignes de code seulement, l'horodatage est réalisé.
Il n'est pas nécessaire de traiter la méthode res.render() car res.render() appelle en interne res.send().
Lors de l'appel de la fonction apply(), il est important de transmettre l'objet res, sinon le this de la fonction de traitement d'origine pointe vers undefined, ce qui conduit directement à une erreur.
Temps de réponse mesuré de la page d'accueil 9 millisecondes
Glossaire QPS :
QPS : Requêtes par seconde signifie « taux de requêtes par seconde », qui est le nombre de requêtes auxquelles un serveur peut répondre. par seconde , est une mesure de la quantité de trafic qu'un serveur de requêtes spécifique gère au cours d'une période de temps spécifiée.
Sur Internet, les performances d'une machine qui sert de serveur de système de noms de domaine sont souvent mesurées par le taux de requêtes par seconde.
TPS : est l'abréviation de TransactionsPerSecond, qui est le nombre de transactions/seconde. Il s'agit d'une unité de mesure pour les résultats des tests logiciels. Une transaction fait référence au processus dans lequel un client envoie une demande au serveur et le serveur répond. Le client commence le chronométrage lorsqu'il envoie une requête et se termine lorsqu'il reçoit la réponse du serveur pour calculer le temps utilisé et le nombre de transactions terminées.
QPS vs TPS : QPS est fondamentalement similaire à TPS, mais la différence est qu'une visite sur une page forme un TPS mais une requête de page peut générer plusieurs requêtes au serveur, et le serveur peut compter ces requêtes comme « QPS ». Par exemple, accéder à une page demandera deux fois au serveur. Un accès générera un « T » et deux « Q ».
.Temps de réponse : temps total nécessaire pour exécuter une requête du début à la fin lorsque les données de réponse sont reçues, c'est-à-dire le temps écoulé entre le lancement de la requête par le client et la réception du résultat de la réponse du serveur.
Le temps de réponse RT (Response-time) est l'un des indicateurs les plus importants d'un système. Sa valeur numérique reflète directement la vitesse du système.
Le nombre de concurrence fait référence au nombre de requêtes que le système peut gérer en même temps. Cela reflète également la capacité de charge du système.
Le débit (capacité de charge) du système est étroitement lié à la consommation CPU des requêtes, des interfaces externes, des E/S, etc. Plus la consommation CPU d'une seule requête est élevée, plus l'interface système externe et la vitesse d'E/S sont lentes, et plus la capacité de débit du système est faible, et vice versa.
Plusieurs paramètres importants du débit du système : QPS (TPS), nombre de simultanéités et temps de réponse.
QPS (TPS) : (Requête par seconde) Nombre de requêtes/transactions par seconde
Concurrence : Nombre de requêtes/transactions traitées par le système en même temps
Temps de réponse : Généralement, le temps de réponse moyen
est calculé après avoir compris la signification de ce qui précède trois éléments. La relation entre eux :
Comprenons les concepts ci-dessus à travers un exemple. Selon la règle des 80/20, si 80 % des visites quotidiennes sont concentrées sur 20 % du temps, ces 20 % du temps sont appelés heures de pointe.
1, 300 W PV par jour sont sur une seule machine. Combien de QPS cette machine nécessite-t-elle ?
(3000000 * 0,8) / (86400 * 0,2) = 139 (QPS)
2. Si le QPS d'une machine est de 58, combien de machines sont nécessaires pour la prendre en charge ?
139 / 58 = 3
À ce stade, si vous réalisez l'architecture frontale de projets généraux de petite et moyenne taille et déployez vos propres services de nœuds, vous saurez combien de machines sont nécessaires pour former un cluster pour rapporter ppt. vous pouvez calculer une valeur approximative avec PV .
Nous devons comprendre le test de stress (nous devons nous appuyer sur le test de stress pour obtenir qps. Prenons l'exemple de la commande ab :
format de commande :
ab [options] [http://]hostname[:port]/path
Common). les paramètres sont les suivants :
-n nombre total de requêtes Nombre de requêtes -c concurrency Nombre de simultanéités -t timelimit Le nombre maximum de secondes pour le test, qui peut être considéré comme le délai d'attente de la requête -p postfile Fichier contenant des données nécessitant le POST -T content-type Informations d'en-tête de type de contenu utilisées par les données POST Copier le code