Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77

NGINX | 12. Dezember 2018

Unabhängig davon, welche Plattform Sie verwenden, ist die Protokollierung häufig eine zentrale Voraussetzung für die Verarbeitung großer Datenmengen, Statistiken, Audits, Kundenberichte und Transaktionen sowie für die Fehlerbehebung bei der Client-Server-Kommunikation und möglichen Problemen.

In diesem Blogbeitrag befassen wir uns mit der Rolle der Protokollierung bei der Fehlerbehebung. Sie ist das wichtigste Werkzeug, um die vielfältigen Probleme aufzuspüren, die bei der Kommunikation über das Internet so häufig auftreten.

Protokollierung bei einer direkten Verbindung zwischen Client und Webserver

Die Protokollierung der Kommunikation zwischen Client und Webserver erleichtert die Fehlerbehebung bei möglichen Problemen im Zusammenhang mit der Browserversion, dem Netzwerk des Clients und den aufgerufenen Dateien erheblich. Doch damit nicht genug: Je nach Plattform und Anforderungen gibt es unzählige weitere Möglichkeiten, Daten zu protokollieren.

Die Protokollierungsarchitektur von NGINX

Wenn Sie einen Reverse-Proxy, Load-Balancer oder ein Content Delivery Network (CDN) betreiben, fügen Sie dem Kommunikationsfluss zwischen Client und Server einen weiteren Knoten hinzu. Ein zwischengeschalteter Server, der Daten verarbeitet, wie etwa ein Reverse-Proxy, führt häufig zu unerwarteten Problemen.

Als Reverse-Proxy wandelt NGINX die Verbindung zwischen Client und Webserver (oder einem anderen Anwendungsserver) in zwei separate Verbindungen um, indem es die Verbindung vom Client beendet und eine neue Verbindung zum Server herstellt. Durch diese „Aufteilung“ in zwei Verbindungen entstehen auch zwei separate Kontexte für die Protokollierung, die NGINX jeweils etwas anders unterstützt.

  • Für den Datenverkehr zwischen dem Client und dem Reverse-Proxy stellt NGINX sowohl ein Fehlerprotokoll als auch ein Zugriffsprotokoll bereit, in dem Verarbeitungsereignisse und Aktionen aufgezeichnet werden, bei denen es sich nicht um Fehler handelt. Das Fehlerprotokoll aktivieren Sie mit der Direktive error_log. Dabei können Sie den Schweregrad der zu protokollierenden Fehler festlegen. Das Zugriffsprotokoll aktivieren Sie mit der Direktive access_log. Mit der zugehörigen Direktive log_format können Sie festlegen, welche Informationen in den Protokollen enthalten sind und wie die Protokolleinträge formatiert werden. Sie können die Protokolle in eine Datei, an syslog oder an beide Ziele schreiben.
  • Für den Datenverkehr zwischen dem Reverse-Proxy und dem Web- oder Anwendungsserver (den NGINX als Upstream-Server bezeichnet) unterstützt NGINX das Fehlerprotokoll. Die Zugriffsprotokollierung für diesen Datenverkehr wird jedoch nicht unterstützt. Die einzige Möglichkeit, Ereignisse zwischen dem Proxyserver und einem Upstream-Server anzuzeigen, bei denen es sich nicht um Fehler handelt, besteht darin, den Schweregrad im Fehlerprotokoll auf debug zu setzen. Der Nachteil dieser Einstellung besteht darin, dass enorme Datenmengen protokolliert werden. Dadurch wird sowohl die Verarbeitung von Anfragen verlangsamt als auch die Erstellung sehr großer Dateien verursacht, die den Speicherplatz schnell aufbrauchen können. (Beachten Sie, dass Sie NGINX außerdem mit dem Argument --with-debug für den Befehl configure neu kompilieren müssen, da die Debugging-Unterstützung standardmäßig nicht aktiviert ist.)

Unsere Lösung für Upstream-Protokolle

Als CDN-Anbieter stoßen wir häufig auf Upstream-Server, die nicht ordnungsgemäß mit unseren Reverse-Proxy-Servern und Clients kommunizieren. Die Meldungen der debug-Stufe im Fehlerprotokoll liefern nicht immer die Informationen, die wir benötigen, um ein Problem mit dem Upstream-Server zu beheben.

Die Lösung lag bald auf der Hand: Wir mussten ein Zugriffsprotokoll für den Upstream-Server erstellen, indem wir eine Funktion hinzufügten, die nur die wesentlichen Informationen aus der Kommunikation zwischen dem Reverse-Proxy und den Upstream-Servern erfasst.

Protokollierung bei einer geteilten Verbindung zwischen Client und Webserver

Die Grundidee besteht darin, dass NGINX unsere Funktion jedes Mal aufruft, wenn eine Anfrage an einen Upstream-Server gestellt wird. Dadurch können wir die gesamte Logik für die Upstream-Protokollierung direkt in der Funktion implementieren.

Das standardmäßige ngx_http_upstream_module verarbeitet Upstream-Anfragen und soll dabei unsere Funktion aufrufen. Da das Modul diese Funktionalität derzeit nicht unterstützt, haben wir es so gepatcht, dass der Callback bei Bedarf ausgeführt wird.

Die Protokollierung selbst erfolgt in einem separaten, von uns entwickelten Modul, das die von uns zum gepatchten Upstream-Modul hinzugefügte Log-Callback-Funktion nutzt. Das neue Modul definiert eine neue Direktive namens „upstream_log“, mit der sich die Protokollierungsfunktion konfigurieren lässt. Die Direktive verwendet denselben Parser wie die Direktive „access_log“, sodass Daten entweder in eine Datei geschrieben oder über einen Socket an einen Syslog-Server gesendet werden können.

Wenn NGINX beim Start die Direktive upstream_log in der Datei nginx.conf einliest, werden zwei Funktionen aufgerufen:

  • ngx_http_upstream_log_set_log, das die Direktive analysiert und die Protokollstruktur selbst (ngx_log_t) intern mithilfe von ngx_log_set_log vorbereitet
  • ngx_http_upstream_log_init (in einem Nachkonfigurationsschritt), wodurch unsere zentrale Protokollierungsfunktion beim Upstream-Modul registriert wird

Auf diese Weise ist alles vorbereitet, wenn eine Anfrage an einen Upstream-Server weitergeleitet werden muss. Das Upstream-Modul stellt eine Verbindung zum Upstream-Server her, und unser Patch sorgt dafür, dass die Logging-Funktion aufgerufen wird, um die Details der Anfrage zu protokollieren.

Das Protokollformat ist fest im Upstream-Modul verankert. Wir haben weiterhin die Möglichkeit, die Konfiguration über die Direktive log_format zu unterstützen, für unseren Anwendungsfall ist dies jedoch nicht erforderlich.

Protokollierte Werte vom Upstream

Die Logging-Funktion wird unmittelbar nach dem Schließen der Verbindung zum Upstream-Server aufgerufen. Ihr Argument ist ein Zeiger auf eine aktuell verarbeitete Anfrage (die Struktur „ngx_http_ request_t“), wodurch die Funktion auf alle Daten in der Struktur zugreifen und diese protokollieren kann. Das Feld „upstream“ (Zeiger auf „ngx_http_upstream_t“) ist von besonderem Interesse, da es Daten zur Upstream-Anfrage enthält. Besonders relevant sind für uns:

  • Der Statuscode der Ursprungsserverantwort
  • Die Dauer der Anfrage
  • Der Wert eines HTTP-Headers in der Antwort oder eines Host-Headers

Der Zugriff auf die gesamte Anfragestruktur verleiht dem Modul seine Flexibilität, da eine Vielzahl von Informationen protokolliert werden kann.

Aufgetretene Probleme

Ursprünglich implementierten wir die Funktionalität im ngx_http_core_module. Für einen Prototyp war dies ausreichend, aber keine besonders saubere Lösung, da sie zukünftige Aktualisierungen und Änderungen erschweren könnte. Schließlich lagerten wir die Upstream-Protokollierungsfunktion in ein eigenständiges Modul aus, wie unter „Unsere Lösung für die Upstream-Protokollierung“ beschrieben.

Natürlich gab es einige Probleme bei der Implementierung. Insbesondere wurden an einigen Stellen ngx_str_t-Zeichenfolgen falsch verarbeitet, beispielsweise indem die C-Bibliotheksfunktion sprintf anstelle von ngx_snprintf verwendet wurde. Dies kann dazu führen, dass undefinierte Daten in das Upstream-Protokoll geschrieben werden oder sogar ein Segmentierungsfehler im Worker-Thread auftritt. Solche Probleme wurden nach umfangreicher Fehlersuche und Tests mit Tools wie Valgrind und AddressSanitizer behoben.

In CDN77 verwendete NGINX-Funktionen

Der Hauptgrund für den Einsatz von NGINX bei CDN77 sind dessen Caching-Funktionen. Der CDN-Server ist ein zwischen Client und Webserver (Upstream-Server) geschalteter Knoten, der Client-Anfragen weiterleitet und die entsprechenden Dateien vom Upstream-Server abruft. Sobald eine Datei im Cache gespeichert ist, wird sie an andere Benutzer ausgeliefert, die dieselbe Datei vom selben Standort anfordern.

„Lokal bereitgestellte Dateien“ ist eine der Funktionen, die wir nutzen, damit NGINX bei Eingang einer Anfrage eine Datei von der Festplatte des Servers bereitstellt.

Für sicheres Caching sind einige zusätzliche Funktionen und Konfigurationen erforderlich. Zum angemessenen Schutz der Inhalte verwenden wir SSL (TLS 1.3 mit 0‑RTT) oder sichere Token, die für eine bestimmte IP-Adresse generiert werden können.

Zu den weiteren von uns genutzten Funktionen gehören individuelle Fehlerseiten für unsere Kunden, die standardmäßige NGINX-Implementierung von OCSP-Stapling sowie FastCGI für PHP, um die Anzahl der erforderlichen PHP-Prozesse zu reduzieren.

Fazit

Das Upstream-Logging hat uns nicht nur bei der Fehlerbehebung verschiedener Probleme geholfen und tut dies auch weiterhin, sondern bot uns auch eine hervorragende Gelegenheit, uns eingehender mit der Kernfunktionalität von NGINX zu befassen, und vereinfachte zahlreiche weitere Projekte, die wir in Angriff genommen haben.

Über CDN77

CDN77 macht die Bereitstellung von Inhalten weltweit besser und komfortabler. Mit mehr als 30 Rechenzentren können wir Inhalte rund um den Globus effizient zwischenspeichern und ausliefern. Dazu gehören statische Inhalte auf Ihrer Website, die Verteilung von Software, Video-on-Demand (VoD) und Live-Streaming über verschiedene Protokolle wie HLS oder MPEG‑DASH mithilfe einer dedizierten Streaming-Engine.

Der Einstieg in CDN77 ist ganz einfach, schnell und unkompliziert. Registrieren Sie sich für eine kostenlose Testversion, erstellen Sie eine CDN-Ressource und verwenden Sie die generierte CDN-URL oder einen benutzerdefinierten CNAME-Eintrag, um CDN77 in Ihre Website oder Streaming-Lösung zu integrieren. Dank der zahlreichen Funktionen, Einstellungen und möglichen individuellen Lösungen erfüllt CDN77 Ihre Anforderungen.


Teilen
Schlagwörter: F5 NGINX, Tech

Über die Autoren

Ähnliche Blogbeiträge

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
NGINX | 23.08.2022

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln

Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
NGINX | 08.09.2021

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen

Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
NGINX | 16.08.2021

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet

Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
NGINX | 12.12.2018

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77

Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.

Ankündigung von NGINX Plus R16
NGINX | 05.09.2018

Ankündigung von NGINX Plus R16

NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
NGINX | 13.10.2016

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing

Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.