Trotz aller Vorteile bringt eine Microservices -Architektur auch neue Komplexitäten mit sich. Eine davon ist die Herausforderung, Anfragen während ihrer Verarbeitung zu verfolgen, wobei die Daten zwischen allen Mikrodiensten fließen, aus denen die Anwendung besteht. Zu diesem Zweck wurde eine neue Methode namens Distributed (Request) Tracing entwickelt. OpenTracing ist eine Spezifikation und ein Standardsatz von APIs, die als Leitfaden für die Entwicklung und Implementierung von Distributed-Tracing-Tools dienen sollen.
In NGINX Plus Release 18 (R18) haben wir das NGINX OpenTracing-Modul zu unserem Repository für dynamische Module hinzugefügt (es ist seit einigen Jahren als Drittanbietermodul auf GitHub verfügbar). Ein großer Vorteil des NGINX OpenTracing-Moduls besteht darin, dass Sie durch die Instrumentierung von NGINX und NGINX Plus für verteiltes Tracing Tracing-Daten für jede geproxiete Anwendung erhalten, ohne die Anwendungen einzeln instrumentieren zu müssen.
In diesem Blog zeigen wir, wie Sie die verteilte Ablaufverfolgung von Anfragen für NGINX oder NGINX Plus aktivieren (der Kürze halber beziehen wir uns von nun an nur noch auf NGINX Plus ). Wir stellen Anweisungen für zwei verteilte Tracing-Dienste ( Tracer in der OpenTracing-Terminologie) bereit, Jaeger und Zipkin . (Eine Liste anderer Tracer finden Sie in der OpenTracing-Dokumentation .) Um die Art der von Tracern bereitgestellten Informationen zu veranschaulichen, vergleichen wir die Anforderungsverarbeitung vor und nach der Aktivierung des NGINX Plus-Caching.
Ein Tracer besteht aus zwei Grundkomponenten:
Der erste Schritt besteht darin, den Server für den Tracer Ihrer Wahl zu installieren und zu konfigurieren. Wir stellen Anweisungen für Jaeger und Zipkin bereit. Passen Sie diese bei Bedarf für andere Tracer an.
Zur Installation des Jaeger-Servers empfehlen wir folgende Vorgehensweise. Sie können Docker-Images auch unter der in Schritt 1 angegebenen URL herunterladen.
Navigieren Sie zur Jaeger-Downloadseite und laden Sie die Linux-Binärdatei herunter (zum Zeitpunkt des Schreibens jaeger-1.12.0-linux-amd64.tar ).
Verschieben Sie die Binärdatei nach /usr/bin/jaeger (erstellen Sie ggf. zuerst das Verzeichnis) und führen Sie sie aus.
$ 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
Überprüfen Sie, ob Sie in Ihrem Browser unter http:// Jaeger-Server-IP-Adresse :16686/ auf die Jaeger-Benutzeroberfläche zugreifen können (16686 ist der Standardport für den Jaeger-Server).
Laden Sie ein Docker-Image von Zipkin herunter und führen Sie es aus (wir verwenden Port 9411, den Standard).
$ docker run -d -p 9411:9411 openzipkin/zipkin
Überprüfen Sie, ob Sie in Ihrem Browser unter http:// Zipkin-Server-IP-Adresse :9411/ auf die Zipkin-Benutzeroberfläche zugreifen können.
Führen Sie diese Befehle auf dem NGINX Plus-Host aus, um das Plug-in für Jaeger oder Zipkin zu installieren.
Installieren Sie das Jaeger-Plug-In. Der folgende wget
-Befehl ist für x86‑64-Linux-Systeme:
$ 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
Anweisungen zum Erstellen des Plug-Ins aus dem Quellcode sind auf GitHub verfügbar.
Erstellen Sie eine JSON‑formatierte Konfigurationsdatei für das Plug‑In mit dem Namen /etc/jaeger/jaeger-config.json und dem folgenden Inhalt. Wir verwenden den Standardport für den Jaeger-Server, 6831:
{ "Dienstname": "nginx", "Sampler": { "Typ": "const", "Param": 1 }, "reporter": { "localAgentHostPort": " Jaeger-Server-IP-Adresse : 6831" } }
Einzelheiten zum Sampler
-Objekt finden Sie in der Jaeger-Dokumentation .
Installieren Sie das Zipkin-Plug-In. Der folgende wget
-Befehl ist für x86‑64-Linux-Systeme:
$ 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
Erstellen Sie eine JSON‑formatierte Konfigurationsdatei für das Plug‑In mit dem Namen /etc/zipkin/zipkin-config.json und dem folgenden Inhalt. Wir verwenden den Standardport für den Zipkin-Server, 9411:
{ "Dienstname": "nginx", "Collector-Host": " Zipkin-Server-IP-Adresse ", "Collector_Port": 9411 }
Einzelheiten zu den Konfigurationsobjekten finden Sie im JSON-Schema auf GitHub .
Führen Sie diese Anweisungen auf dem NGINX Plus-Host aus.
Installieren Sie das NGINX OpenTracing-Modul gemäß den Anweisungen im NGINX Plus Admin Guide .
Fügen Sie die folgende load_module-
Direktive im Hauptkontext (oberste Ebene) der Hauptkonfigurationsdatei von NGINX Plus ( /etc/nginx/nginx.conf ) hinzu:
lade_Module Module/ngx_http_opentracing_module.so;
Fügen Sie der NGINX Plus-Konfiguration die folgenden Anweisungen hinzu.
Wenn Sie das herkömmliche Konfigurationsschema verwenden, fügen Sie die Anweisungen in eine neue Datei mit dem Namen /etc/nginx/conf.d/opentracing.conf ein. Überprüfen Sie außerdem, ob die folgende Include
-Direktive im HTTP-
Kontext in /etc/nginx/nginx.conf erscheint:
http {
include /etc/nginx/conf.d/*.conf;
}
„opentracing_load_tracer“
aktiviert das Tracer-Plugin. Entfernen Sie je nach Bedarf die Kommentarzeichen aus der Direktive für Jaeger oder Zipkin.opentracing_tag
-Direktiven machen NGINX Plus-Variablen als OpenTracing-Tags verfügbar, die in der Tracer-Benutzeroberfläche angezeigt werden.log_format
und access_log
auf. Wenn Sie das standardmäßige NGINX-Zugriffsprotokoll und -Protokollformat durch dieses ersetzen möchten, heben Sie die Kommentierung der Anweisungen auf und ändern Sie dann die drei Instanzen von „ opentracing
“ in „ main
“. Eine andere Möglichkeit besteht darin, die OpenTracing-Aktivität nur für den Datenverkehr auf Port 9001 zu protokollieren. Entfernen Sie dazu die Kommentarzeichen aus den Anweisungen log_format
und access_log
und verschieben Sie sie in den Serverblock
.Serverblock
richtet OpenTracing für die im nächsten Abschnitt beschriebene Beispiel-Ruby-Anwendung ein.# Laden Sie einen 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;
# Aktivieren Sie die Ablaufverfolgung für alle Anfragen
opentracing on;
# Legen Sie zusätzliche Tags fest, die den Wert der NGINX Plus-Variablen erfassen
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;
#Kommentare zum Debuggen entfernen
# 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 / {
# Der für OpenTracing Spans verwendete Operationsname ist standardmäßig der Name des
# 'location'-Blocks, aber heben Sie die Kommentierung dieser Anweisung auf, um sie anzupassen.
#opentracing_operation_name $uri;
# Verbreiten Sie den aktiven Span-Kontext nach oben, damit die Ablaufverfolgung
# vom Backend fortgesetzt werden kann.
opentracing_propagate_context;
# Stellen Sie sicher, dass Ihre Ruby-App auf Port 4567 lauscht
proxy_pass http://127.0.0.1:4567;
}
}
Validieren und laden Sie die NGINX Plus-Konfiguration neu:
$ nginx -t $ nginx -s neu laden
Mit der Tracer- und NGINX Plus-Konfiguration erstellen wir eine Beispiel-Ruby-App, die zeigt, wie OpenTracing-Daten aussehen. Mit der App können wir messen, um wie viel das NGINX Plus-Caching die Reaktionszeit verbessert. Wenn die App eine Anfrage wie die folgende HTTP- GET-
Anfrage für / empfängt, wartet sie eine zufällige Zeitspanne (zwischen 2 und 5 Sekunden), bevor sie antwortet.
$ curl http:// NGINX-Plus-IP-Adresse :9001/
Installieren und richten Sie sowohl Ruby als auch Sinatra ein (eine Open-Source-Software-Webanwendungsbibliothek und domänenspezifische Sprache, die in Ruby als Alternative zu anderen Ruby-Webanwendungs-Frameworks geschrieben ist).
Erstellen Sie eine Datei namens app.rb mit folgendem Inhalt:
#!/usr/bin/ruby
require 'sinatra'
get '/*' do
out = "<h1>Ruby simple app</h1>" + "\n"
#Schlafe eine zufällige Zeit zwischen 2 und 5 Sekunden
sleeping_time = rand(4)+2
sleep(sleeping_time)
puts "geschlafen für: #{sleeping_time}s."
out += '<p>irgendein Ausgabetext</p>' + "\n"
return out
end
Machen Sie app.rb ausführbar und führen Sie es aus:
$ chmod +x app.rb $ ./app.rb
Wir verwenden Jaeger und Zipkin, um zu zeigen, wie lange NGINX Plus braucht, um auf eine Anfrage zu antworten, wenn das Caching nicht aktiviert ist. Für jeden Tracer senden wir fünf Anfragen.
Hier sind die fünf Anfragen, die in der Jaeger-Benutzeroberfläche angezeigt werden (aktuellste zuerst):
Hier sind die gleichen Informationen auf der Ruby-App-Konsole:
- -> /geschlafen für: 3 Sek.
127.0.0.1 - - [07/Jun/2019: 10:50:46 +0000] „GET / HTTP/1.1“ 200 49 3.0028
127.0.0.1 - - [07.06.2019: 10:50:43 UTC] „GET / HTTP/1.0“ 200 49
- -> /
geschlafen für: 2 Sek.
127.0.0.1 - - [07/Jun/2019: 10:50:56 +0000] "GET / HTTP/1.1" 200 49 2.0018
127.0.0.1 - - [07.06.2019: 10:50:54 UTC] „GET / HTTP/1.0“1 200 49
- -> /
geschlafen für: 3 Sek.
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
- -> /
geschlafen für: 4 Sek.
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
- -> /
geschlafen für: 3 Sek.
127.0.0.1 - - [07/Jun/2019: 10:54:11 +0000] „GET / HTTP/1.1“ 200 49 3.0012
127.0.0.1 - - [07.06.2019: 10:54:08 UTC] "GET / HTTP/1.0" 200 49
In der Jaeger-Benutzeroberfläche klicken wir auf die erste (aktuellste) Anfrage, um Details dazu anzuzeigen, einschließlich der Werte der NGINX Plus-Variablen, die wir als Tags hinzugefügt haben:
Hier sind weitere fünf Anfragen in der Zipkin-Benutzeroberfläche:
Dieselben Informationen auf der Ruby-App-Konsole:
- -> /geschlafen für: 2 Sek.
127.0.0.1 - - [07/Jun/2019: 10:31:18 +0000] "GET / HTTP/1.1" 200 49 2.0021
127.0.0.1 - - [07.06.2019: 10:31:16 UTC] „GET / HTTP/1.0“ 200 49
- -> /
geschlafen für: 3 Sek.
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
- -> /
geschlafen für: 3 Sek.
127.0.0.1 - - [07/Jun/2019: 10:32:08 +0000] "GET / HTTP/1.1" 200 49 3.0026
127.0.0.1 - - [07.06.2019: 10:32:05 UTC] „GET / HTTP/1.0“ 200 49
- -> /
geschlafen für: 3 Sek.
127.0.0.1 - - [07/Jun/2019: 10:32:32 +0000] "GET / HTTP/1.1" 200 49 3.0015
127.0.0.1 - - [07.06.2019: 10:32:29 UTC] „GET / HTTP/1.0“ 200 49
- -> /
geschlafen für: 5 Sek.
127.0.0.1 - - [07/Jun/2019: 10:32:52 +0000] "GET / HTTP/1.1" 200 49 5.0030
127.0.0.1 - - [07.06.2019: 10:32:47 UTC] "GET / HTTP/1.0" 200 49
In der Zipkin-Benutzeroberfläche klicken wir auf die erste Anfrage, um Details dazu anzuzeigen, einschließlich der Werte der NGINX Plus-Variablen, die wir als Tags hinzugefügt haben:
Wir aktivieren das Caching , indem wir Anweisungen zur Datei opentracing.conf hinzufügen, die wir unter „Konfigurieren von NGINX Plus“ erstellt haben.
Fügen Sie im HTTP
-Kontext diese Proxy_Cache_Path-
Direktive hinzu:
Proxy-Cache-Pfad /Daten/nginx/Cache Keys_Zone=one:10m;
Fügen Sie im Serverblock
die folgenden Anweisungen proxy_cache
und proxy_cache_valid
hinzu:
proxy_cache eins;
proxy_cache_valid beliebig 1m;
Überprüfen und laden Sie die Konfiguration neu:
$ nginx -t $ nginx -s neu laden
Hier ist die Jaeger-Benutzeroberfläche nach zwei Anfragen.
Die erste Antwort (mit der Bezeichnung 13f69db ) dauerte 4 Sekunden. NGINX Plus hat die Antwort zwischengespeichert, und als die Anforderung etwa 15 Sekunden später wiederholt wurde, dauerte die Antwort weniger als 2 Millisekunden (ms), da sie aus dem NGINX Plus-Cache kam.
Bei genauerer Betrachtung der beiden Anfragen wird der Unterschied in der Antwortzeit deutlich. Bei der ersten Anfrage lautet upstream_cache_status
MISS
, was bedeutet, dass die angeforderten Daten nicht im Cache waren. Die Ruby-App hat eine Verzögerung von 4 Sekunden hinzugefügt.
Für die zweite Anfrage lautet upstream_cache_status
HIT
. Da die Daten aus dem Cache kommen, kann die Ruby-App keine Verzögerung hinzufügen und die Reaktionszeit beträgt weniger als 2 ms. Die leeren upstream_*-
Werte zeigen auch an, dass der Upstream-Server nicht an dieser Antwort beteiligt war.
Die Anzeige in der Zipkin-Benutzeroberfläche für zwei Anfragen mit aktiviertem Caching zeichnet ein ähnliches Bild:
Und wenn man sich die beiden Anfragen noch einmal im Detail ansieht, erklärt sich der Unterschied in der Antwortzeit. Die Antwort wird für die erste Anforderung nicht zwischengespeichert ( upstream_cache_status
ist MISS
) und die Ruby-App fügt (zufällig) dieselbe 4-Sekunden- Verzögerung hinzu wie im Jaeger-Beispiel.
Die Antwort wurde zwischengespeichert, bevor wir die zweite Anfrage stellen, daher ist upstream_cache_status
HIT
.
Das NGINX OpenTracing-Modul ermöglicht die Verfolgung von NGINX Plus-Anfragen und -Antworten und bietet Zugriff auf NGINX Plus-Variablen mithilfe von OpenTracing-Tags. Auch verschiedene Tracer können mit diesem Modul verwendet werden.
Weitere Einzelheiten zum NGINX OpenTracing-Modul finden Sie im NGINX OpenTracing- Modul-Repo auf GitHub.
Um OpenTracing mit NGINX Plus auszuprobieren, starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen .
„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."