njs est un interpréteur JavaScript dans un serveur Web léger avec lequel vous pouvez créer de nouvelles variables nginx et demander des gestionnaires d'étape. À quoi sert njs? Qu'est-ce qui ne peut pas? Et pourquoi l'ont-ils fait? Dmitry Volyntsev (
xeioex ), le développeur nginx et le développeur principal de l'interpréteur njs répondront à ces questions et à d'autres.

- Dmitry, pourquoi aviez-vous besoin de scripts dans les configurations nginx?
- La première raison est la directive
if
. Les personnes qui l'ont vue pour la première fois pensent qu'elles peuvent être utilisées impérativement. En fait, ce n'est pas le cas - la configuration de nginx est déclarative. Dans l'exemple ci-dessous, vous pourriez penser que la réponse aura deux en-têtes: X-First et X-Second. Mais seul le deuxième en-tête obtiendra la réponse, car nginx est ainsi arrangé: si nous écrivons deux directives if, alors la dernière sera sélectionnée.
location /only-one-if { set $true 1; if ($true) { add_header X-First 1; } if ($true) { add_header X-Second 2; }
La deuxième raison est ce à quoi Nginx est arrivé maintenant. Auparavant, il était utilisé pour mettre en cache les statistiques et les requêtes, ainsi que l'équilibrage de charge - un ensemble de proxy classique. La prolifération des microservices a érodé la portée de nginx. Si les paramètres de configuration précédents se terminaient par une paire d'emplacements sur plusieurs backends dans certaines langues, alors avec l'architecture de microservice, nous avons plus de pièces mobiles. Le backend est devenu un tas de petits composants. La logique d'autorisation, par exemple, doit être dupliquée sur chaque microservice ou supprimée, par exemple, sur le frontend. Pour implémenter l'autorisation avancée, il n'y a pas toujours suffisamment de mécanismes de solution intégrés dans nginx.
Troisièmement, dans nginx, de nombreuses directives acceptent des expressions calculées dynamiquement, par exemple:
proxy cache bypass $cookie_nocache $arg_nocache;
Vous pouvez concaténer des variables entre elles ou avec des chaînes littérales. Mais cela ne suffit pas, et j'aimerais avoir des outils plus puissants, par exemple, pour calculer le hachage, pour travailler avec des données numériques, pour convertir en majuscules et minuscules.
Pour développer tous les goulots d'étranglement dans nginx, vous devez soit développer votre propre syntaxe, soit utiliser quelque chose de prêt à l'emploi. Nous sommes arrivés à la conclusion qu'il est préférable de prendre un langage de programmation de script existant. Ainsi, les développeurs n'ont pas besoin d'apprendre une nouvelle langue, ce qui permettra également de gagner du temps et d'abaisser le seuil d'entrée. Nous avons choisi JavaScript.
- Et pourquoi JavaScript?
- Nous avons choisi JavaScript pour plusieurs raisons:
- Un dialecte moderne, ce qui est bon pour les développeurs qui passent d'autres langues.
- Style en C. Ceci est important car la configuration nginx utilise des accolades et à l'avenir, nous voulons ajouter la possibilité d'écrire du code JS directement dans la configuration. Les accolades nous aideront avec cela. À Lua, par exemple, le rôle des accolades est joué par le début et la fin - ce qui n'est pas pratique.
- Le modèle JavaScript correspond bien à l'architecture nginx.
"Alors Lua a également été envisagée?" Est-ce à cause du début et de la fin?
- Il existe déjà un projet tiers prêt à l'emploi OpenResty. Si vous n'entrez pas dans les détails, il s'agit essentiellement de nginx + Lua, mais il a une architecture qui va à l'encontre de nginx. Nous voulions éviter les intersections avec cet écosystème. De plus, il y a plusieurs autres raisons:
- Lua a une syntaxe de type pascal.
- Les tableaux sont indexés à partir de 1.
- Lua est toujours un langage de programmation de niche.
- Comment se compare njs avec ses concurrents?
- Nous avons évalué njs en comparaison avec les moteurs bien connus - V8 et SpiderMonkey. Ils sont inefficaces pour les tâches à l'intérieur de nginx, car ils sont affinés par les navigateurs et très lourds, et nginx nécessite une vitesse élevée. De plus, ces deux moteurs évoluent rapidement, leur API est instable. Enfin, njs peut être intégré plus efficacement dans nginx:
Le nombre de contextes créés par seconde- Quelles sont les normes prises en charge par njs?
- Pour le moment, presque tous les éléments de base de la spécification ECMAScript 5.1 sont implémentés avec quelques entrecoupements des éléments des spécifications 6 et 7. Autrement dit, des objets standard tels que Object, Array, String, Number, Date, RegExp, JSON. Les fermetures, les fonctions anonymes et le travail avec exceptions sont entièrement pris en charge.
Nous ne nous fixons pas comme objectif principal la pleine conformité avec les spécifications linguistiques. Donc pour le moment il n'y a pas de support pour
eval () , et pour l'instant nous ne prévoyons pas de l'ajouter. Mais nous prévoyons d'ajouter la prise en charge des mots clés const et let, ainsi que des fonctions fléchées.
Qu'est-ce qui est capable et ce qui n'est pas capable de njs pour le momentIl est important de mentionner une dernière chose: le manque de collecte des ordures. La plupart des langages modernes contrôlent indépendamment la durée de vie des objets. Si l'objet n'est plus utilisé, il est automatiquement supprimé. Vous ne pouvez pas vous passer de ce mécanisme, mais vous devez généralement y sacrifier quelque chose - le travail du programme ralentit, voire s’arrête. Dans njs, la mémoire n'est libérée que lorsque l'objet de requête est libéré.
Cette approche a ses avantages et ses inconvénients. Le principal inconvénient est qu'il ne vous permet pas de travailler efficacement avec de longues requêtes. Par conséquent, à l'avenir, nous prévoyons d'ajouter la récupération de place comme option pour l'activer au besoin.
- Qu'est-ce qui n'est pas njs?
- Avant de répondre à cette question, je voudrais répéter une fois de plus que la tâche principale de njs est d'étendre les capacités de configuration flexible de nginx et de résoudre les tâches du côté proxy.
Maintenant, la question elle-même. Que faut-il considérer à l'avance?
- njs ne remplace pas Node.js.
- Le bundle nginx + njs n'est pas un serveur d'applications.
- njs n'implémente pas complètement les normes ECMAScript, car il n'y a pas de support pour eval ().
Si ce sujet est extrêmement pertinent pour vous et que vous souhaitez plus de détails, nous vous recommandons de regarder l'enregistrement vidéo du rapport de Dmitry Volintsev à HighLoad ++ Siberia 2018, où il l'a révélé de tous les côtés.
Nous invitons également tous les professionnels à soumettre leurs rapports à la conférence
HighLoad ++ 2018 de novembre, qui se tiendra à Skolkovo les 8 et 9 novembre. Si vous avez une expérience unique et intéressante et que vous êtes prêt à la partager - inscrivez-vous avant le 1er septembre et remplissez le
formulaire .
Si vous avez peur de parler en public, nous avons une soi-disant
école de conférenciers , où nous aidons à pomper ces compétences gratuitement.