Les 5 principaux développeurs de nœuds d’erreurs

Node est une plateforme fantastique pour écrire des backends. Sauf quand on ne fait pas les choses correctement.


Selon le côté de la clôture sur lequel vous vous trouvez, Node est la meilleure ou la pire chose qui puisse arriver au monde du développement Web. Mais malgré les opinions, on ne peut pas contester la popularité de Node. Il a grimpé en popularité beaucoup plus rapidement que quiconque ne s’y attendait, même son créateur (il l’a dit dans un autre sens pessimiste entretien)!

Au moment de l’écriture, c’est la plate-forme par défaut pour démarrer de nouvelles applications, ce qui, je l’avoue, est souvent le résultat de la mentalité du troupeau, mais l’effet net est qu’il y a plus d’emplois, plus d’argent et plus de projets passionnants dans Node que dans d’autres langages de script traditionnels.

Malheureusement, lorsque quelqu’un me demande de leur recommander une pile de démarrage pour le développement Web ou de nouveaux produits de démarrage, Node est ma recommandation n ° 1, même si je connais bien PHP et Laravel..

Si je pouvais être autorisé à continuer un peu la diatribe (ce que je serai puisque je suis celui qui écrit?), Les ennemis de Node ont raison de dire que leur pile Web préférée peut faire les choses aussi bien que Node, mais l’inverse est également vrai. Et puis il y a des choses comme la programmation et les événements asynchrones, qui ont été intégrés dans Node dès le premier jour, et d’autres écosystèmes essaient maintenant désespérément de copier.

Aujourd’hui, nous avons des options asynchrones en PHP et Python, mais malheureusement, le cœur des bibliothèques populaires existantes est purement synchrone, c’est donc presque comme si vous vous battiez contre le système. Mais quoi qu’il en soit, assez de diatribes pour une journée. ��

Donc, si vous êtes un développeur Node (débutant ou familier), il est probable que vous commettiez l’une de ces grosses erreurs qui affectent négativement votre application. C’est peut-être parce que vous n’êtes pas familier avec une façon particulière d’améliorer les choses dans Node, ou peut-être que ce sont simplement des habitudes que vous avez transférées d’un autre écosystème..

Ne pas respecter la boucle d’événement

Lorsqu’une personne migre vers Node, c’est en partie parce qu’elle a entendu des histoires sur la façon dont LinkedIn évolue à l’aide de Node, ou qu’elle a vu des benchmarks qui montrent que Node exécute des cercles autour de PHP, Ruby, etc. lorsqu’il s’agit de traiter des demandes par seconde ou de gérer connexions de socket ouvertes.

Donc, ils construisent leur application, s’attendant aux mêmes temps de réponse explosifs qu’ils rêvaient – sauf que rien de proche ne se produit.

L’une des principales raisons à cela n’est pas de bien comprendre la boucle d’événements. Considérez le code suivant qui obtient un ensemble de livres de la base de données, puis les trie par le nombre total de pages:

db.Library.get (libraryId, fonction (err, bibliothèque) {
let books = library.books;
books.sort (fonction (a, b) {
retourner a.pages < b.pages? -1: 1
});
});

Je suis d’accord que ce code ne fait rien avec le tableau des livres triés, mais ce n’est pas le point ici. Le fait est qu’un code aussi innocent suffit à faire exploser la boucle des événements dès que vous commencez à traiter un nombre non trivial de livres.

La raison en est que la boucle d’événements est destinée à effectuer des E / S non bloquantes. Un bon exemple est celui d’un emballeur de pizza dans une pizzeria – la personne est spécialisée dans la découpe de la pizza, le pliage des couvercles dans des boîtes de livraison, la mise de la pizza, la pose des bonnes étiquettes et la pousser vers le livreur.

Incroyable, non? Tout comme Node!

Source: stackoverflow.com

Mais réfléchissez à ce qui se passera si cette personne doit également mélanger, préparer et emballer les assaisonnements. Selon la complexité du processus, le taux d’emballage de pizza sera réduit d’un tiers, voire peut-être même complètement arrêté..

C’est ce que nous entendons par des tâches qui «bloquent» – tant que Node doit simplement transmettre des informations, c’est très rapide et idéalement la meilleure option, mais dès qu’il a besoin de faire des calculs approfondis, il s’arrête, et tout sinon il faut attendre. Cela se produit car la boucle d’événements est monothread (plus de détails ici.)

Donc, n’effectuez pas de calculs dans la boucle d’événements, quelle que soit leur importance. Je veux dire, ajouter des nombres et prendre des moyennes est bien, mais de grands ensembles de données feront analyser votre application Node.

En espérant que le code asynchrone coopérera

Considérez cet exemple de nœud très simple qui lit les données d’un fichier et les affiche:

const fs = require (‘fs’);

laissez contents = fs.readFile (‘secret.txt’, (err, data) => {
renvoyer des données;
});

console.log (‘Le contenu du fichier est:’);
console.log (contenu);

L’exposition aux langages classiques (comme PHP, Python, Perl, Ruby, C ++, etc.) vous fera appliquer le bon sens qu’après l’exécution de ce code, le contenu de la variable aura le contenu du fichier. Mais voici ce qui se passe lorsque vous exécutez réellement le code:

Nous obtenons undefined (). C’est parce que même si vous vous souciez profondément de Node, sa nature asynchrone ne se soucie pas de vous (c’est censé être une blague! Veuillez ne pas spammer de commentaires haineux ici ��). Notre travail consiste à comprendre sa nature asynchrone et à travailler avec elle. readFile () est une fonction asynchrone, ce qui signifie que dès qu’elle est appelée, la boucle d’événement Node transmet le travail au composant du système de fichiers et continue.

Il revient à la fonction plus tard lorsque le fichier a été lu, mais à ce moment le contenu est traité comme une variable non initialisée et contient donc undefined. La bonne façon est de traiter les données du fichier dans la fonction de rappel, mais je ne peux pas entrer dans plus de détails car ce n’est pas un Tutoriel sur les nœuds. ��

Rappel qui appelle le rappel qui appelle le rappel qui appelle . . .

JavaScript est plus proche de la programmation fonctionnelle que tout autre langage traditionnel plus ancien (en fait, tout est dit et fait, c’est mon préféré en matière de conception orientée objet et de capacités fonctionnelles – je le mets au-dessus de Python, PHP, Perl, Java et même Ruby quand il s’agit d’écrire du code “agréable”).

Autrement dit, les fonctions obtiennent plus de droits des citoyens que dans d’autres langues. Ajoutez à cela le fait que le code asynchrone fonctionne en vous fournissant une fonction de rappel, et nous nous retrouvons avec une recette pour une catastrophe connue sous le nom de Callback Hell.

Voici un exemple de code Electron que j’ai rencontré sur Quora. Que pensez-vous que cela fait?

options var;

require (‘électron’). app.once (
‘prêt’,

une fonction () {

options = {
cadre: faux,
hauteur: 768,
largeur: 1024,
x: 0,
y: 0
};

options.BrowserWindow = require (‘electron’). BrowserWindow;
options.browserWindow = nouvelles options.BrowserWindow (options);
options.browserWindow.loadURL (‘http://electron.atom.io’);
options.browserWindow.webContents.once (
«did-stop-loading»,

une fonction () {
options.browserWindow.capturePage (
les options,

fonction (données) {
require (‘fs’). writeFileSync (
‘/tmp/screenCapture.testExampleJs.browser..png’,
data.toPng ()
);

process.exit (0);
}
);
}
);
}
);

Si vous avez du mal, rejoignez le club!

Les fonctions à l’intérieur des fonctions à l’intérieur des fonctions sont difficiles à lire et très difficiles à raisonner, c’est pourquoi il a été appelé «enfer de rappel» (je suppose que l’enfer est un endroit déroutant pour sortir!). Bien que cela fonctionne techniquement, vous rendez votre code à l’épreuve du futur contre toute tentative de compréhension et de maintenance.

Il existe de nombreuses façons d’éviter l’enfer de rappel, y compris Promesses et Extensions réactives.

Ne pas utiliser tous les cœurs de CPU

Les processeurs modernes ont plusieurs cœurs – 2, 4, 8, 16, 32. . . le nombre continue de grimper.

Mais ce n’est pas ce que le créateur de Node avait en tête lorsqu’il a sorti Node. Par conséquent, le nœud est à un seul thread, ce qui signifie qu’il s’exécute à l’intérieur d’un seul thread (ou processus, si vous voulez l’appeler ainsi, bien qu’ils ne soient pas les mêmes), en utilisant un seul cœur de processeur.

Cela signifie que si vous avez appris Node à partir de didacticiels et d’amis et d’extraits de code flottant et que votre application est déployée sur un serveur à 8 cœurs, vous perdez 7/8 de la puissance de traitement disponible.!

Inutile de dire que c’est un énorme gaspillage. Si vous suivez ce chemin, vous finirez par payer pour huit serveurs lorsque vous n’en aurez besoin que d’un. C’est-à-dire dépenser 16 000 $ par mois quand 2 000 $ suffiront (la perte d’argent fait toujours mal, non??). Tout cela, quand la solution est assez simple: utiliser le grappe module.

Je ne peux pas entrer dans tous les détails ici, mais c’est une technique simple pour détecter le nombre de cœurs de la machine actuelle, puis lancer autant d’instances de nœuds. Lorsque des erreurs sont détectées, l’instance est redémarrée. Voici à quel point il est simple à mettre en œuvre (tutoriel ici):

var cluster = require (‘cluster’);

if (cluster.isMaster) {
var numWorkers = require (‘os’). cpus (). length;

console.log (‘Configuration du cluster principal’ + numWorkers + ‘workers …’);

pour (var i = 0; i < numWorkers; i ++) {
cluster.fork ();
}

cluster.on (‘en ligne’, fonction (travailleur) {
console.log (‘Worker’ + worker.process.pid + ‘est en ligne’);
});

cluster.on (‘exit’, fonction (travailleur, code, signal) {
console.log (‘Worker’ + worker.process.pid + ‘est mort avec le code:’ + code + ‘et le signal:’ + signal);
console.log (‘Démarrage d’un nouveau travailleur’);
cluster.fork ();
});
} autre {
var app = require (‘express’) ();
app.all (‘/ *’, fonction (req, res) {res.send (‘processus’ + process.pid + ‘dit bonjour!’). end ();})

var server = app.listen (8000, function () {
console.log (‘Processus’ + process.pid + ‘écoute toutes les requêtes entrantes’);
});
}

Comme vous pouvez le voir, cluster.fork () fait la magie, et le reste écoute simplement quelques événements de cluster essentiels et fait le nettoyage nécessaire.

Ne pas utiliser TypeScript

D’accord, ce n’est pas une erreur en tant que telle, et de nombreuses applications Node ont été et sont écrites sans TypeScript.

Cela dit, TypeScript offre les garanties et la tranquillité d’esprit dont Node a toujours eu besoin, et à mes yeux, c’est une erreur si vous développez pour Node en 2019 et que vous n’utilisez pas TypeScript (en particulier lorsque le A (angulaire) de la pile MEAN est déplacé. à TypeScript il y a longtemps).

La transition est douce et TypeScript est presque exactement comme le JavaScript que vous connaissez, avec la garantie des types, ES6 et quelques autres vérifications:

// /lib/controllers/crmController.ts
importer * comme mangouste de ‘mangouste’;
importer {ContactSchema} de ‘../models/crmModel’;
importer {Request, Response} depuis ‘express’;

const Contact = mongoose.model (‘Contact’, ContactSchema);
classe d’exportation ContactController {

public addNewContact (req: Request, res: Response) {
let newContact = new Contact (req.body);

newContact.save ((err, contact) => {
si (err) {
res.send (err);
}
res.json (contact);
});
}

Je recommanderais de vérifier cette gentille et amicale Tutoriel TypeScript.

Conclusion

Le nœud est impressionnant, mais ce n’est pas sans ses (nombreux?) Problèmes. Cela dit, cela s’applique à toutes les technologies existantes, nouvelles et anciennes, et nous ferons mieux de comprendre Node et de travailler avec lui..

J’espère que ces cinq conseils vous éviteront d’être aspirés dans le goudron de bogues pérennes et de problèmes de performances. Si j’ai raté quelque chose d’intéressant, faites-le-moi savoir et je serai plus qu’heureux (en fait, reconnaissant!) De les inclure dans l’article. ��

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map