Éditeur – L’article de blog intitulé « Introduction au module JavaScript NGINX » redirige ici. L'article a été mis à jour avec les directives et fonctionnalités du module JavaScript NGINX prises en charge à partir d'avril 2021.
Le module JavaScript NGINX (njs) est devenu disponible en tant que module stable dans NGINX Open Source 1.11.10 et NGINX Plus R12 . [Le module s'appelait à l'origine nginScript, et ce nom apparaît dans certains articles plus anciens.] Nous avons travaillé sans relâche sur NGINX JavaScript depuis son lancement en septembre 2015 , en ajoutant les fonctionnalités et la prise en charge linguistique incluses dans le module stable.
NGINX JavaScript est une implémentation JavaScript unique pour NGINX et NGINX Plus, conçue spécifiquement pour les cas d'utilisation côté serveur et le traitement par requête. Il étend la syntaxe de configuration NGINX avec du code JavaScript afin d'implémenter des solutions de configuration sophistiquées.
Les cas d'utilisation sont nombreux, d'autant plus que le module JavaScript NGINX est disponible pour les protocoles HTTP et TCP/UDP. Voici quelques exemples de cas d'utilisation pour NGINX JavaScript :
Avant de discuter plus en détail de NGINX JavaScript, abordons d’abord deux idées fausses courantes.
La communauté NGINX a créé plusieurs extensions programmatiques au fil des ans. Au moment de la rédaction de cet article, Lua est le plus populaire d'entre eux ; il est disponible en tant que module pour NGINX et en tant que module dynamique tiers pré-construit et pris en charge pour NGINX Plus. Le module Lua et les bibliothèques complémentaires offrent une intégration approfondie avec le cœur NGINX et un riche ensemble de fonctionnalités, notamment un pilote pour Redis.
Lua est un langage de script puissant. Il reste cependant assez limité en termes d’adoption et ne se trouve généralement pas dans la « boîte à outils de compétences » du développeur front-end ou de l’ingénieur DevOps.
NGINX JavaScript ne cherche pas à remplacer Lua et il faudra un certain temps avant que NGINX JavaScript ait un niveau de fonctionnalité comparable. L'objectif de NGINX JavaScript est de fournir des solutions de configuration programmatique à la communauté la plus large possible en utilisant un langage de programmation populaire.
NGINX JavaScript n'a pas pour objectif de transformer NGINX ou NGINX Plus en un serveur d'applications. En termes simples, les cas d’utilisation de NGINX JavaScript s’apparentent à ceux d’un middleware, car l’exécution du code JavaScript se produit entre le client et le contenu. Techniquement parlant, bien que Node.js partage deux choses avec la combinaison de NGINX JavaScript et NGINX ou NGINX Plus – une architecture pilotée par événements et le langage de programmation JavaScript – les similitudes s'arrêtent là.
Node.js utilise le moteur JavaScript Google V8, tandis que NGINX JavaScript est une implémentation sur mesure des normes ECMAScript, conçue spécifiquement pour NGINX et NGINX Plus. Node.js dispose d'une machine virtuelle JavaScript persistante (VM) en mémoire et effectue une collecte de routine des déchets pour la gestion de la mémoire, tandis que NGINX JavaScript initialise une nouvelle VM JavaScript et la mémoire nécessaire pour chaque demande et libère la mémoire lorsque la demande est terminée.
Comme mentionné ci-dessus, NGINX JavaScript est une implémentation sur mesure du langage JavaScript. Tous les autres moteurs d’exécution JavaScript existants sont conçus pour être exécutés dans un navigateur Web. La nature de l’exécution de code côté client diffère de celle du code côté serveur à bien des égards, de la disponibilité des ressources système au nombre possible d’exécutions simultanées.
Nous avons décidé d’implémenter notre propre runtime JavaScript afin de répondre aux exigences d’exécution de code côté serveur et de s’adapter élégamment à l’architecture de traitement des requêtes de NGINX. Nos principes de conception pour NGINX JavaScript sont les suivants :
L'environnement d'exécution vit et meurt avec la demande
Le module JavaScript NGINX utilise l’exécution de bytecode à thread unique, conçue pour une initialisation et une suppression rapides. L'environnement d'exécution est initialisé par requête. Le démarrage est extrêmement rapide, car il n’y a pas d’état complexe ni d’aide à initialiser. La mémoire est accumulée dans des pools pendant l'exécution et libérée à la fin en libérant les pools. Ce schéma de gestion de la mémoire élimine le besoin de suivre et de libérer des objets individuels ou d'utiliser un récupérateur de mémoire.
Exécution de code non bloquante
Le modèle piloté par événements de NGINX et NGINX Plus planifie l’exécution d’environnements d’exécution JavaScript NGINX individuels. Lorsqu'une règle JavaScript NGINX exécute une opération de blocage (comme la lecture de données réseau ou l'émission d'une sous-requête externe), NGINX et NGINX Plus suspendent de manière transparente l'exécution de la machine virtuelle JavaScript NGINX associée et la replanifient une fois l'événement terminé. Cela signifie que vous pouvez écrire des règles de manière simple et linéaire et que NGINX et NGINX Plus les planifient sans blocage interne.
Implémenter uniquement la prise en charge linguistique dont nous avons besoin
Les spécifications de JavaScript sont définies par les normes ECMAScript . NGINX JavaScript suit ECMAScript 5.1 avec un peu d' ECMAScript 6 pour les fonctions mathématiques. L’implémentation de notre propre environnement d’exécution JavaScript nous donne la liberté de prioriser la prise en charge linguistique pour les cas d’utilisation côté serveur et d’ignorer ce dont nous n’avons pas besoin. Nous maintenons une liste des éléments linguistiques actuellement pris en charge .
Intégration étroite avec les phases de traitement des demandes
NGINX et NGINX Plus traitent les demandes en phases distinctes. Les directives de configuration fonctionnent généralement à une phase spécifique et les modules NGINX natifs profitent souvent de la possibilité d'inspecter ou de modifier une demande à une phase particulière. NGINX JavaScript expose certaines des phases de traitement via des directives de configuration pour donner le contrôle sur le moment où le code JavaScript est exécuté. Cette intégration avec la syntaxe de configuration promet la puissance et la flexibilité des modules NGINX natifs avec la simplicité du code JavaScript.
Le tableau ci-dessous indique quelles phases de traitement sont accessibles via NGINX JavaScript au moment de la rédaction, ainsi que les directives de configuration qui les fournissent.
Phase de traitement | Module HTTP | Module de flux |
---|---|---|
Accès – Authentification et contrôle d’accès |
auth_request et js_content |
js_access |
Pré-lecture – Charge utile en lecture/écriture |
N / A | js_preread |
Filtre – Réponse en lecture/écriture pendant le proxy |
js_body_filter js_header_filter |
js_filter |
Contenu – Envoyer une réponse au client |
js_content |
N / A |
Log / Variables – Évaluées à la demande |
js_set |
js_set |
NGINX JavaScript est implémenté sous la forme d'un module que vous pouvez compiler dans un binaire NGINX Open Source ou charger dynamiquement dans NGINX ou NGINX Plus. Les instructions pour activer NGINX JavaScript avec NGINX et NGINX Plus apparaissent à la fin de cet article.
Dans cet exemple, nous utilisons NGINX ou NGINX Plus comme proxy inverse simple et utilisons NGINX JavaScript pour construire des entrées de journal d'accès dans un format spécialisé, qui :
La configuration NGINX pour cet exemple est extrêmement simple.
Comme vous pouvez le voir, le code JavaScript NGINX n’est pas conforme à la syntaxe de configuration. Au lieu de cela, nous utilisons la directive js_import
pour spécifier le fichier qui contient tout notre code JavaScript. La directive js_set
définit une nouvelle variable NGINX, $access_log_headers
, et la fonction JavaScript qui la remplit. La directive log_format
définit un nouveau format appelé kvpairs qui écrit chaque ligne de journal avec la valeur de $access_log_headers
.
Le bloc serveur
définit un proxy inverse HTTP simple qui transmet toutes les requêtes à https://www.example.com . La directive access_log
spécifie que toutes les demandes seront enregistrées avec le format kvpairs .
Regardons maintenant le code JavaScript qui prépare une entrée de journal.
La valeur de retour de la fonction kvAccess
– une entrée de journal – est transmise à la directive de configuration js_set
dans rawheader_logging.conf . Gardez à l’esprit que les variables NGINX sont évaluées à la demande et cela signifie à son tour que la fonction JavaScript définie par js_set
est exécutée lorsque la valeur de la variable est requise. Dans cet exemple, $access_log_headers
est utilisé dans la directive log_format
et donc kvAccess()
est exécuté au moment de la journalisation. Les variables utilisées dans le cadre des directives de mappage
ou de réécriture
(non illustrées dans cet exemple) déclenchent l'exécution JavaScript correspondante à une phase de traitement antérieure.
Nous pouvons voir cette solution de journalisation améliorée par JavaScript NGINX en action en transmettant une requête via notre proxy inverse et en observant l'entrée du fichier journal résultant, qui comprend des en-têtes de requête avec le préfixe in.
et des en-têtes de réponse avec le préfixe out
.
$ curl http://127.0.0.1/ $ tail --lines=1 /var/log/nginx/access_headers.log 2021-04-23T10:08:15+00:00 client=172.17.0.1 méthode=GET uri=/index.html état=200 in.Host=localhost:55081 in.User-Agent=curl/7.64.1 in.Accept=*/* out.Content-Type=text/html out.Content-Length=612 out.ETag=\x22606339ef-264\x22 out.Accept-Ranges=octets
Une grande partie de l’utilité de NGINX JavaScript résulte de son accès aux composants internes de NGINX. Cet exemple utilise plusieurs propriétés de l'objet request( r
) . Le module JavaScript Stream NGINX (pour les applications TCP et UDP) utilise un ou plusieurs
objets de session avec son propre ensemble de propriétés. Pour d'autres exemples de solutions JavaScript NGINX pour HTTP et TCP/UDP, voir Cas d'utilisation du module JavaScript NGINX .
Nous aimerions connaître les cas d’utilisation que vous proposez pour NGINX JavaScript – veuillez nous en parler dans la section commentaires ci-dessous.
Consultez ces articles de blog pour découvrir d’autres cas d’utilisation HTTP et TCP/UDP pour le module JavaScript NGINX :
auth_request
avec le module JavaScript NGINX dans « Validation des jetons d'accès OAuth 2.0 avec NGINX et NGINX Plus »
[nom de ngx_snippet = 'njs-enable-instructions']
« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."