Malgré tous ses avantages, une architecture de microservices introduit également de nouvelles complexités. L’une d’elles consiste à suivre les requêtes au fil de leur traitement, tandis que les données circulent entre tous les microservices qui composent l’application. Une nouvelle méthodologie appelée traçage distribué (des requêtes) a été créée à cette fin, et OpenTracing est une spécification et un ensemble standard d’API destinés à guider la conception et la mise en œuvre d’outils de traçage distribué.
Dans NGINX Plus version 18 (R18), nous avons ajouté le module NGINX OpenTracing à notre dépôt de modules dynamiques (il était déjà disponible en tant que module tiers sur GitHub depuis quelques années). L’un des principaux avantages du module NGINX OpenTracing est qu’en instrumentant NGINX et NGINX Plus pour le traçage distribué, vous obtenez des données de traçage pour chaque application faisant l’objet d’un proxy, sans avoir à instrumenter les applications individuellement.
Dans cet article, nous expliquons comment activer le traçage distribué des requêtes pour NGINX ou NGINX Plus (par souci de concision, nous parlerons simplement de NGINX Plus dans la suite de cet article). Nous fournissons des instructions pour deux services de traçage distribué (appelés traceurs dans la terminologie OpenTracing), Jaeger et Zipkin. (Pour obtenir la liste des autres traceurs, consultez la documentation OpenTracing.) Afin d’illustrer le type d’informations fournies par les traceurs, nous comparons le traitement des requêtes avant et après l’activation de la mise en cache de NGINX Plus.
Un traceur comporte deux composants de base :
- Un agent qui collecte les données de traçage des applications exécutées sur l’hôte sur lequel il s’exécute. Dans notre cas, l’« application » est NGINX Plus et l’agent est implémenté sous forme de plug-in.
- Un serveur (également appelé le « collecteur ») qui accepte les données de traçage provenant d’un ou de plusieurs agents et les affiche dans une interface utilisateur centralisée. Vous pouvez exécuter le serveur sur l’hôte NGINX Plus ou sur un autre hôte, selon votre préférence.
Installation d’un serveur de traçage
La première étape consiste à installer et à configurer le serveur pour l’outil de traçage de votre choix. Nous fournissons des instructions pour Jaeger et Zipkin ; adaptez-les si nécessaire pour d’autres outils de traçage.
Installation du serveur Jaeger
Nous vous recommandons d’utiliser la méthode suivante pour installer le serveur Jaeger. Vous pouvez également télécharger les images Docker à l’URL indiquée à l’étape 1.
- Accédez à la page de téléchargement de Jaeger et téléchargez le fichier binaire Linux (au moment de la rédaction, jaeger-1.12.0-linux-amd64.tar).
- Déplacez le fichier binaire vers « /usr/bin/jaeger » (en créant d’abord le répertoire si nécessaire), puis exécutez-le.
$ mkdir /usr/bin/jaeger$ mv jaeger-1.12.0-linux-amd64.tar /usr/bin/jaeger
$ cd /usr/bin/jaeger
$ tar xvzf jaeger-1.12.0-linux-amd64.tar.gz
$ sudo rm -rf jaeger-1.12.0-linux-amd64.tar.gz
$ cd jaeger-1.12.0-linux-amd64
$ ./jaeger-all-in-one- Vérifiez que vous pouvez accéder à l’interface utilisateur de Jaeger dans votre navigateur à l’adresse http://adresse-IP-du-serveur-Jaeger:16686/ (16686 est le port par défaut du serveur Jaeger).
Installation du serveur Zipkin
- Téléchargez et exécutez une image Docker de Zipkin (nous utilisons le port 9411, qui est le port par défaut).
$ docker run -d -p 9411:9411 openzipkin/zipkin- Vérifiez que vous pouvez accéder à l’interface utilisateur de Zipkin dans votre navigateur à l’adresse http://adresse-IP-du-serveur-Zipkin:9411/.
Installation et configuration d’un plug-in de traçage
Exécutez ces commandes sur l’hôte NGINX Plus pour installer le plug-in pour Jaeger ou Zipkin.
Installation du plug-in Jaeger
- Installez le plug-in Jaeger. La commande
wgetsuivante est destinée aux systèmes Linux x86-64 :
$ cd /usr/local/lib
$ wget https://github.com/jaegertracing/jaeger-client-cpp/releases/download/v0.4.2/libjaegertracing_plugin.linux_amd64.so -O /usr/local/lib/libjaegertracing_plugin.so- Les instructions pour compiler le plug-in à partir du code source sont disponibles sur GitHub.
- Créez un fichier de configuration au format JSON pour le plug-in, nommé /etc/jaeger/jaeger-config.json, avec le contenu suivant. Nous utilisons le port par défaut du serveur Jaeger, à savoir 6831 :
{ "service_name": "nginx",
"sampler": {
"type": "const",
"param": 1
},
"reporter": {
"localAgentHostPort": "Jaeger-server-IP-address:6831"
}
}- Pour plus d’informations sur l’objet
sampler, consultez la documentation de Jaeger.
Installation du plug-in Zipkin
- Installez le plug-in Zipkin. La commande
wgetsuivante est destinée aux systèmes Linux x86-64 :
$ cd /usr/local/lib$ wget -O - https://github.com/rnburn/zipkin-cpp-opentracing/releases/download/v0.5.2/linux-amd64-libzipkin_opentracing_plugin.so.gz | gunzip -c > /usr/local/lib/libzipkin_opentracing_plugin.so- Créez un fichier de configuration au format JSON pour le plug-in, nommé /etc/zipkin/zipkin-config.json, avec le contenu suivant. Nous utilisons le port par défaut du serveur Zipkin, à savoir le port 9411 :
{ "service_name": "nginx",
"collector_host": "Zipkin-server-IP-address",
"collector_port": 9411
}- Pour plus d’informations sur les objets de configuration, consultez le schéma JSON sur GitHub.
Configuration de NGINX Plus
Effectuez ces opérations sur l’hôte NGINX Plus.
- Installez le module OpenTracing de NGINX en suivant les instructions du guide d’administration de NGINX Plus.
- Ajoutez la directive
load_modulesuivante dans le contexte principal (niveau supérieur) du fichier de configuration principal de NGINX Plus (/etc/nginx/nginx.conf) :
load_module modules/ngx_http_opentracing_module.so;- Ajoutez les directives suivantes à la configuration de NGINX Plus. Si vous utilisez le « schéma de configuration conventionnel », placez les directives dans un nouveau fichier nommé « /etc/nginx/conf.d/opentracing.conf ». Vérifiez également que la directive «
include» suivante figure dans le contexte «http» du fichier « /etc/nginx/nginx.conf » :
http {
include /etc/nginx/conf.d/*.conf;
}# Load a vendor tracer#opentracing_load_tracer /usr/local/libjaegertracing_plugin.so
# /etc/jaeger/jaeger-config.json;
#opentracing_load_tracer /usr/local/lib/libzipkin_opentracing_plugin.so
# /etc/zipkin/zipkin-config.json;
# Enable tracing for all requests
opentracing on;
# Set additional tags that capture the value of NGINX Plus variables
opentracing_tag bytes_sent $bytes_sent;
opentracing_tag http_user_agent $http_user_agent;
opentracing_tag request_time $request_time;
opentracing_tag upstream_addr $upstream_addr;
opentracing_tag upstream_bytes_received $upstream_bytes_received;
opentracing_tag upstream_cache_status $upstream_cache_status;
opentracing_tag upstream_connect_time $upstream_connect_time;
opentracing_tag upstream_header_time $upstream_header_time;
opentracing_tag upstream_queue_time $upstream_queue_time;
opentracing_tag upstream_response_time $upstream_response_time;
#uncomment for debugging
# log_format opentracing '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for" '
# '"$host" sn="$server_name" '
# 'rt=$request_time '
# 'ua="$upstream_addr" us="$upstream_status" '
# 'ut="$upstream_response_time" ul="$upstream_response_length" '
# 'cs=$upstream_cache_status';
#access_log /var/log/nginx/opentracing.log opentracing;
server {
listen 9001;
location / {
# The operation name used for OpenTracing Spans defaults to the name of the
# 'location' block, but uncomment this directive to customize it.
#opentracing_operation_name $uri;
# Propagate the active Span context upstream, so that the trace can be
# continued by the backend.
opentracing_propagate_context;
# Make sure that your Ruby app is listening on port 4567
proxy_pass http://127.0.0.1:4567;
}
}- La directive «
opentracing_load_tracer» active le plug-in de traçage. Décommentez la directive correspondant à Jaeger ou à Zipkin, selon le cas. - Les directives
opentracing_tagrendent les variables NGINX Plus disponibles sous forme de balises OpenTracing qui apparaissent dans l’interface utilisateur du traceur. - Pour déboguer l’activité OpenTracing, décommentez les directives
log_formatetaccess_log. Si vous souhaitez remplacer le journal d’accès et le format de journal NGINX par défaut par ceux-ci, décommentez les directives, puis remplacez les trois occurrences de «opentracing» par «main». Vous pouvez également consigner l’activité OpenTracing uniquement pour le trafic sur le port 9001 : décommentez les directiveslog_formatetaccess_log, puis déplacez-les dans le blocserver. - Le bloc
serverconfigure OpenTracing pour l’exemple d’application Ruby décrit dans la section suivante.
- Validez et rechargez la configuration de NGINX Plus :
$ nginx -t$ nginx -s reloadConfiguration de l’application Ruby d’exemple
Une fois le traceur et NGINX Plus configurés, nous créons un exemple d’application Ruby qui illustre les données OpenTracing. Cette application nous permet de mesurer dans quelle mesure la mise en cache de NGINX Plus améliore le temps de réponse. Lorsque l’application reçoit une requête telle que la requête HTTP GET suivante pour /, elle attend un délai aléatoire (compris entre 2 et 5 secondes) avant de répondre.
$ curl http://NGINX-Plus-IP-address:9001/- Installez et configurez à la fois Ruby et Sinatra (une bibliothèque open source pour applications web et un langage dédié écrit en Ruby, qui constitue une alternative aux autres frameworks d’applications web Ruby).
- Créez un fichier nommé « app.rb » avec le contenu suivant :
#!/usr/bin/ruby
require 'sinatra'
get '/*' do
out = "<h1>Ruby simple app</h1>" + "\n"
#Sleep a random time between 2s and 5s
sleeping_time = rand(4)+2
sleep(sleeping_time)
puts "slept for: #{sleeping_time}s."
out += '<p>some output text</p>' + "\n"
return out
end- Rendez app.rb exécutable et lancez-le :
$ chmod +x app.rb$ ./app.rbSuivi des temps de réponse sans mise en cache
Nous utilisons Jaeger et Zipkin pour mesurer le temps nécessaire à NGINX Plus pour répondre à une requête lorsque la mise en cache n’est pas activée. Pour chaque outil de traçage, nous envoyons cinq requêtes.
Résultats de Jaeger sans mise en cache
Voici les cinq requêtes affichées dans l’interface utilisateur de Jaeger (de la plus récente à la plus ancienne) :

Voici les mêmes informations dans la console de l’application Ruby :
- -> /slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:50:46 +0000] "GET / HTTP/1.1" 200 49 3.0028
127.0.0.1 - - [07/Jun/2019: 10:50:43 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 2s.
127.0.0.1 - - [07/Jun/2019: 10:50:56 +0000] "GET / HTTP/1.1" 200 49 2.0018
127.0.0.1 - - [07/Jun/2019: 10:50:54 UTC] "GET / HTTP/1.0"1 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:53:16 +0000] "GET / HTTP/1.1" 200 49 3.0029
127.0.0.1 - - [07/Jun/2019: 10:53:13 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 4s.
127.0.0.1 - - [07/Jun/2019: 10:54:03 +0000] "GET / HTTP/1.1" 200 49 4.0030
127.0.0.1 - - [07/Jun/2019: 10:53:59 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:54:11 +0000] "GET / HTTP/1.1" 200 49 3.0012
127.0.0.1 - - [07/Jun/2019: 10:54:08 UTC] "GET / HTTP/1.0" 200 49Dans l’interface utilisateur de Jaeger, nous cliquons sur la première requête (la plus récente) pour en afficher les détails, notamment les valeurs des variables NGINX Plus que nous avons ajoutées en tant que balises :

Résultat de Zipkin sans mise en cache
Voici cinq autres requêtes dans l’interface utilisateur de Zipkin :

Les mêmes informations dans la console de l’application Ruby :
- -> /slept for: 2s.
127.0.0.1 - - [07/Jun/2019: 10:31:18 +0000] "GET / HTTP/1.1" 200 49 2.0021
127.0.0.1 - - [07/Jun/2019: 10:31:16 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:31:50 +0000] "GET / HTTP/1.1" 200 49 3.0029
127.0.0.1 - - [07/Jun/2019: 10:31:47 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:32:08 +0000] "GET / HTTP/1.1" 200 49 3.0026
127.0.0.1 - - [07/Jun/2019: 10:32:05 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 3s.
127.0.0.1 - - [07/Jun/2019: 10:32:32 +0000] "GET / HTTP/1.1" 200 49 3.0015
127.0.0.1 - - [07/Jun/2019: 10:32:29 UTC] "GET / HTTP/1.0" 200 49
- -> /
slept for: 5s.
127.0.0.1 - - [07/Jun/2019: 10:32:52 +0000] "GET / HTTP/1.1" 200 49 5.0030
127.0.0.1 - - [07/Jun/2019: 10:32:47 UTC] "GET / HTTP/1.0" 200 49Dans l’interface utilisateur de Zipkin, nous cliquons sur la première requête pour en afficher les détails, notamment les valeurs des variables NGINX Plus que nous avons ajoutées en tant que tags :

Suivi des temps de réponse avec la mise en cache
Configuration de la mise en cache de NGINX Plus
Nous activons la mise en cache en ajoutant des directives dans le fichier opentracing.conf que nous avons créé dans la section « Configuration de NGINX Plus ».
- Dans le contexte
http, ajoutez cette directiveproxy_cache_path:
proxy_cache_path /data/nginx/cache keys_zone=one:10m;- Dans le bloc
server, ajoutez les directivesproxy_cacheetproxy_cache_validsuivantes :
proxy_cache one;
proxy_cache_valid any 1m;- Validez et rechargez la configuration :
$ nginx -t$ nginx -s reloadRésultat de Jaeger avec mise en cache
Voici l’interface utilisateur de Jaeger après deux requêtes.

La première réponse (identifiée par « 13f69db ») a pris 4 secondes. NGINX Plus a mis la réponse en cache et, lorsque la requête a été répétée environ 15 secondes plus tard, la réponse a pris moins de 2 millisecondes (ms), car elle provenait du cache de NGINX Plus.
L’examen détaillé des deux requêtes explique la différence de temps de réponse. Pour la première requête, upstream_cache_status indique MISS, ce qui signifie que les données demandées ne se trouvaient pas dans le cache. L’application Ruby a ajouté un délai de 4 secondes.

Pour la deuxième requête, « upstream_cache_status » vaut « HIT ». Comme les données proviennent du cache, l’application Ruby ne peut pas ajouter de délai et le temps de réponse est inférieur à 2 ms. Les valeurs « upstream_* » vides indiquent également que le serveur en amont n’est pas intervenu dans cette réponse.

Résultat de Zipkin avec mise en cache
L’affichage dans l’interface utilisateur de Zipkin pour deux requêtes avec la mise en cache activée présente un résultat similaire :

Là encore, l’examen détaillé des deux requêtes explique la différence de temps de réponse. La réponse n’est pas mise en cache pour la première requête (upstream_cache_status vaut MISS) et l’application Ruby ajoute (par coïncidence) le même délai de 4 secondes que dans l’exemple Jaeger.

La réponse a été mise en cache avant que nous n’effectuions la deuxième requête, donc « upstream_cache_status » vaut « HIT ».

Conclusion
Le module OpenTracing de NGINX permet de tracer les requêtes et les réponses NGINX Plus, et donne accès aux variables NGINX Plus à l’aide de balises OpenTracing. Différents traceurs peuvent également être utilisés avec ce module.
Pour plus d’informations sur le module NGINX OpenTracing, consultez le dépôt du module NGINX OpenTracing sur GitHub.
Pour essayer OpenTracing avec NGINX Plus, commencez dès aujourd’hui votre essai gratuit de 30 jours ou contactez-nous pour discuter de vos cas d’utilisation.
À propos de l’auteur
Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.
Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.
Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.
Caches partagés avec les clusters de cache NGINX Plus, partie 1
Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.
Introduction aux microservices
Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.