Einführung – So wird NGINX mit Python verwendet
Python ist dafür bekannt, einfach zu bedienen zu sein und Spaß zu machen, die Softwareentwicklung zu erleichtern und eine Laufzeitleistung zu bieten, die andere Skriptsprachen übertreffen soll. (Allerdings könnte die neueste PHP-Version, PHP 7, Python durchaus Konkurrenz machen.)
Jeder möchte, dass seine Website und Anwendung schneller läuft. Zudem ist jede Website mit wachsendem Datenverkehr oder starken Lastspitzen anfällig für Leistungsprobleme und Ausfallzeiten, die häufig zu den ungünstigsten – also den am stärksten frequentierten – Zeiten auftreten. Darüber hinaus leiden nahezu alle Websites unter Leistungsproblemen und Ausfallzeiten, unabhängig davon, ob das Datenverkehrsaufkommen stetig wächst oder die Nutzung plötzlich stark ansteigt.
Hier kommen NGINX und NGINX Plus ins Spiel. Sie verbessern die Website-Performance auf drei verschiedene Arten:
- Als Webserver – NGINX wurde ursprünglich entwickelt, um das C10K-Problem zu lösen – also problemlos 10.000 oder mehr gleichzeitige Verbindungen zu unterstützen. Wenn Sie NGINX als Webserver für Ihre Python-App einsetzen, wird Ihre Website selbst bei geringem Datenverkehr schneller. Bei mehreren Tausend Nutzern sorgt NGINX mit hoher Wahrscheinlichkeit für eine deutlich höhere Leistung, weniger Abstürze und geringere Ausfallzeiten. Sie können auf Ihrem NGINX-Webserver auch statische Dateien zwischenspeichern oder Microcaching einsetzen. Beides funktioniert jedoch besser auf einem separaten NGINX-Reverse-Proxy-Server (siehe nächster Absatz).
- Als Reverse-Proxy-Server – Sie können NGINX als Reverse-Proxy-Server vor Ihrer bestehenden Anwendungsserver-Konfiguration einsetzen. NGINX ist dem Web zugewandt und leitet Anfragen an Ihren Anwendungsserver weiter. Dieser „eine ungewöhnliche Trick“ beschleunigt Ihre Website, reduziert Ausfallzeiten, verbraucht weniger Serverressourcen und verbessert die Sicherheit. Außerdem können Sie statische Dateien auf dem Reverse-Proxy-Server zwischenspeichern (sehr effizient), Microcaching dynamischer Inhalte hinzufügen, um die Anwendung selbst zu entlasten, und vieles mehr.
- Als Load Balancer für mehrere Anwendungsserver – Stellen Sie zunächst einen Reverse-Proxy-Server bereit. Skalieren Sie anschließend horizontal, indem Sie mehrere Anwendungsserver parallel betreiben und den Datenverkehr mithilfe von NGINX oder NGINX Plus auf diese verteilen. Mit dieser Art der Bereitstellung können Sie die Leistung Ihrer Website problemlos entsprechend den Datenverkehrsanforderungen skalieren und so die Zuverlässigkeit und Verfügbarkeit erhöhen. Wenn eine bestimmte Benutzersitzung auf demselben Server verbleiben soll, konfigurieren Sie den Load Balancer so, dass er Sitzungspersistenz unterstützt.
NGINX und NGINX Plus bieten Vorteile, unabhängig davon, ob Sie sie als Webserver für Ihre Python-Anwendung, als Reverse-Proxy-Server, als Load Balancer oder für alle drei Zwecke einsetzen.
In diesem ersten Artikel einer zweiteiligen Reihe stellen wir fünf Tipps zur Leistungssteigerung Ihrer Python-Apps vor. Dazu gehören der Einsatz von NGINX und NGINX Plus als Webserver, die Implementierung der Zwischenspeicherung statischer Dateien und das Microcaching anwendungsgenerierter Dateien. In Teil 2 beschreiben wir, wie Sie NGINX und NGINX Plus als Reverse-Proxy-Server und als Load Balancer für mehrere Anwendungsserver einsetzen.
Tipp 1 – Leistungsengpässe in Python finden
Es gibt zwei sehr unterschiedliche Situationen, in denen die Performance Ihrer Python-Anwendung eine Rolle spielt: zum einen bei einer alltäglichen, „überschaubaren“ Anzahl von Nutzern und zum anderen unter hoher Last. Viele Websitebetreiber machen sich bei geringer Last zu wenig Gedanken über die Performance, obwohl sie unserer bescheidenen Meinung nach um jede Zehntelsekunde Reaktionszeit kämpfen sollten. Reaktionszeiten um Millisekunden zu verkürzen, ist eine schwierige und undankbare Aufgabe, doch sie macht die Nutzer zufriedener und verbessert die Geschäftsergebnisse.
Dieser Blogbeitrag und der dazugehörige zweite Teil konzentrieren sich jedoch auf das Szenario, das tatsächlich allen Sorgen bereitet: Leistungsprobleme, die bei hoher Auslastung einer Website auftreten, etwa erhebliche Leistungseinbußen und Abstürze. Zudem ähneln die Auswirkungen vieler Hackerangriffe denen eines plötzlichen Anstiegs der Nutzerzahlen, und die Verbesserung der Websiteleistung ist häufig auch ein wichtiger Schritt bei der Abwehr von Angriffen.
Bei einem System wie Apache HTTP Server, das jedem Benutzer eine bestimmte Menge an Arbeitsspeicher zuweist, führt eine steigende Benutzerzahl dazu, dass der physische Arbeitsspeicher zunehmend überlastet wird. Der Server beginnt, Daten auf die Festplatte auszulagern, die Leistung bricht ein und es kommt zu Leistungseinbußen und Abstürzen. Der in diesem Blogbeitrag beschriebene Umstieg auf NGINX trägt zur Lösung dieses Problems bei.
Python ist besonders anfällig für speicherbedingte Leistungsprobleme, da es für seine Aufgaben in der Regel mehr Arbeitsspeicher benötigt als andere Skriptsprachen (und sie dadurch schneller ausführt). Unter ansonsten gleichen Bedingungen kann Ihre Python-basierte App daher bereits bei einer geringeren Benutzerlast „zusammenbrechen“ als eine in einer anderen Sprache geschriebene App.
Die Optimierung Ihrer App kann bis zu einem gewissen Grad helfen, ist aber in der Regel weder der beste noch der schnellste Weg, um durch hohen Datenverkehr verursachte Leistungsprobleme Ihrer Website zu lösen. Die in diesem Blogbeitrag und im zugehörigen Teil 2 beschriebenen Schritte sind die besten und schnellsten Maßnahmen, um solche Leistungsprobleme zu beheben. Nachdem Sie die hier beschriebenen Schritte umgesetzt haben, können Sie selbstverständlich Ihre App weiter verbessern oder sie so umschreiben, dass sie eine Microservices-Architektur verwendet.
Tipp 2 – Wählen Sie eine Einzelserver- oder Multiserver-Bereitstellung
Kleine Websites lassen sich problemlos auf einem einzelnen Server betreiben. Große Websites benötigen mehrere Server. Wenn Sie sich jedoch in der Grauzone dazwischen befinden – oder Ihre Website von einer kleinen zu einer großen Website heranwächst –, müssen Sie einige interessante Entscheidungen treffen.
Wenn Ihre Bereitstellung auf einem einzelnen Server läuft, besteht bei Lastspitzen oder einem schnellen Anstieg des gesamten Datenverkehrs ein erhebliches Risiko. Ihre Skalierbarkeit ist begrenzt. Mögliche Abhilfemaßnahmen sind die Optimierung Ihrer App, die Umstellung Ihres Webservers auf NGINX, die Anschaffung eines größeren und schnelleren Servers oder die Auslagerung von Speicherinhalten an ein Content Delivery Network (CDN). Jede dieser Optionen erfordert Zeit für die Umsetzung, verursacht Kosten und birgt das Risiko, dass dabei Fehler oder Probleme entstehen.
Außerdem hat Ihre Website bei einer Bereitstellung auf einem einzelnen Server per Definition einen Single Point of Failure – und für viele der Probleme, die Ihre Website außer Betrieb setzen können, gibt es keine schnellen oder einfachen Lösungen.

Wenn Sie Ihren Server in einer Einzelserver-Bereitstellung auf NGINX umstellen, können Sie frei zwischen NGINX Open Source und NGINX Plus wählen. NGINX Plus umfasst Support auf Enterprise-Niveau und zusätzliche Funktionen. Einige der zusätzlichen Funktionen, wie etwa die Live-Aktivitätsüberwachung, sind für eine Einzelserver-Bereitstellung relevant, während andere, wie etwa Lastverteilung und Sitzungspersistenz, zum Tragen kommen, wenn Sie NGINX Plus als Reverse-Proxy-Server in einer Mehrserver-Bereitstellung verwenden.
Alles in allem birgt eine Einzelserver-Bereitstellung gewisse Risiken, es sei denn, Sie sind sicher, dass Ihre Website noch lange klein bleiben wird und Ausfallzeiten kein großes Problem darstellen. Eine Mehrserver-Bereitstellung lässt sich nahezu beliebig skalieren – einzelne Ausfallpunkte können durch entsprechende technische Maßnahmen beseitigt werden, und die Leistung lässt sich nach Bedarf anpassen, wobei zusätzliche Kapazitäten schnell bereitgestellt werden können.
Tipp 3 – Wechseln Sie mit Ihrem Webserver zu NGINX
In den Anfangstagen des Internets war der Name „Apache“ gleichbedeutend mit „Webserver“. NGINX wurde jedoch Anfang der 2000er-Jahre entwickelt und erfreut sich stetig wachsender Beliebtheit; bei den Webservern auf Platz 1 der weltweit 1.000, 10.000, 100.000 und [ngx_snippet name=’proportion-top-sites’] meistbesuchten Websites.
NGINX wurde entwickelt, um das C10K-Problem zu lösen, also mehr als 10.000 gleichzeitige Verbindungen innerhalb eines vorgegebenen Speicherbudgets zu verarbeiten. Andere Webserver benötigen für jede Verbindung einen Speicherblock. Dadurch geht ihnen der physische Speicher aus, sodass sie langsamer werden oder abstürzen, wenn Tausende von Benutzern gleichzeitig auf eine Website zugreifen möchten. NGINX verarbeitet jede Anfrage separat und lässt sich problemlos für eine wesentlich größere Anzahl von Benutzern skalieren. (Wie wir weiter unten erläutern, eignet es sich auch hervorragend für weitere Zwecke.)
Nachfolgend finden Sie einen allgemeinen Überblick über die Architektur von NGINX.

Im Diagramm gehört ein Python-Anwendungsserver in den Anwendungsserver-Block im Backend. Der Zugriff darauf erfolgt über FastCGI. NGINX „weiß“ nicht, wie Python ausgeführt wird, und benötigt daher ein Gateway zu einer Umgebung, die dazu in der Lage ist. FastCGI ist eine weitverbreitete Schnittstelle für PHP, Python und andere Sprachen.
Eine beliebtere Wahl für die Kommunikation zwischen Python und NGINX ist jedoch das Web Server Gateway Interface (WSGI). WSGI funktioniert in Umgebungen mit mehreren Threads und Prozessen und lässt sich daher bei allen in diesem Blogbeitrag genannten Bereitstellungsoptionen gut skalieren.
Wenn Sie zu NGINX als Webserver wechseln, finden Sie umfangreiche Unterstützung für die erforderlichen Schritte:
- Gunicorn konfigurieren – „Green Unicorn“, ein beliebter WSGI-Server, für die Verwendung mit NGINX.
- uWSGI konfigurieren – Ein weiterer beliebter WSGI-Server für die Verwendung mit NGINX. uWSGI bietet direkte Unterstützung für NGINX.
- uWSGI, NGINX und Django verwenden – Ein beliebtes Python-Webframework.
Dieses Beispiel zeigt, wie Sie NGINX für die Verwendung mit uWSGI konfigurieren können – in diesem Fall für ein Projekt, das das Python-Framework Django verwendet:
http { # ...
upstream django {
server 127.0.0.1:29000;
}
server {
listen 80;
server_name myapp.example.com;
root /var/www/myapp/html;
location / {
index index.html;
}
location /static/ {
alias /var/django/projects/myapp/static/;
}
location /main {
include /etc/nginx/uwsgi_params;
uwsgi_pass django;
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
}
}
}Tipp 4 – Caching für statische Dateien implementieren
Beim Caching statischer Inhalte wird eine Kopie von Dateien, die sich nicht allzu häufig ändern – also vielleicht nur alle paar Stunden oder überhaupt nie –, an einem anderen Ort als dem Anwendungsserver gespeichert. Ein typisches Beispiel für statische Inhalte ist ein JPEG-Bild, das als Teil einer Webseite angezeigt wird.
Das Caching statischer Dateien ist eine gängige Methode zur Verbesserung der Anwendungsleistung und findet auf mehreren Ebenen statt:
- Im Browser des Benutzers
- Bei Internetanbietern auf verschiedenen Ebenen – vom internen Netzwerk eines Unternehmens bis hin zu einem Internetdienstanbieter (ISP)
- Auf einem Webserver, wie wir hier beschreiben werden
Die Implementierung der Zwischenspeicherung statischer Dateien auf dem Webserver bietet zwei Vorteile:
- Schnellere Bereitstellung für den Benutzer – NGINX ist für das Caching statischer Dateien optimiert und verarbeitet Anfragen nach statischen Inhalten deutlich schneller als ein Anwendungsserver.
- Geringere Belastung des Anwendungsservers – Der Anwendungsserver erhält Anfragen nach zwischengespeicherten statischen Dateien gar nicht erst, da der Webserver sie beantwortet.
Das Caching statischer Dateien funktioniert bei einer Implementierung mit nur einem Server gut, allerdings teilen sich Webserver und Anwendungsserver weiterhin die zugrunde liegende Hardware. Wenn der Webserver die Hardware mit dem Abrufen einer zwischengespeicherten Datei beschäftigt – selbst wenn dies sehr effizient geschieht – stehen diese Hardwareressourcen der Anwendung nicht zur Verfügung, wodurch sie möglicherweise etwas verlangsamt wird.
Um Browser-Caching zu unterstützen, legen Sie die HTTP-Header für statische Dateien korrekt fest. Berücksichtigen Sie den HTTP-Header „Cache-Control“ (insbesondere dessen Einstellung „max-age“), den Header „Expires“ und die „Entity“-Tags. Eine gute Einführung in das Thema finden Sie unter „NGINX und NGINX Plus als Anwendungs-Gateway mit uWSGI und Django verwenden“ im NGINX Plus-Administratorhandbuch.
Mit dem folgenden Code wird NGINX so konfiguriert, dass statische Dateien im Cache gespeichert werden, darunter JPEG-, GIF- und PNG-Dateien, MP4-Videodateien, PowerPoint-Dateien und viele weitere. Ersetzen Sie www.example.com durch die URL Ihres Webservers.
server { # substitute your web server's URL for "www.example.com"
server_name www.example.com;
root /var/www/example.com/htdocs;
index index.php;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
try_files $uri =404;
include fastcgi_params;
# substitute the socket, or address and port, of your Python server
fastcgi_pass unix:/var/run/php5-fpm.sock;
#fastcgi_pass 127.0.0.1:9000;
}
location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg
|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid
|midi|wav|bmp|rtf)$ {
expires max;
log_not_found off;
access_log off;
}
}Tipp 5 – Microcaching implementieren
Microcaching bietet enormes Potenzial zur Leistungssteigerung auf Anwendungsservern, auf denen Python, PHP und andere Sprachen ausgeführt werden. Im Hinblick auf das Caching gibt es drei Arten von Webseiten:
- Statische Dateien – Diese können wie in Tipp 4 beschrieben zwischengespeichert werden.
- Von der Anwendung generierte, nicht personalisierte Seiten – In der Regel ist es nicht sinnvoll, diese zwischenzuspeichern, da sie aktuell sein müssen. Ein Beispiel ist eine Seite, die einem nicht angemeldeten Benutzer eines Onlineshops angezeigt wird (siehe nächster Punkt) – die verfügbaren Produkte, Empfehlungen für ähnliche Produkte und dergleichen können sich ständig ändern, weshalb es wichtig ist, eine aktuelle Seite bereitzustellen. Ruft jedoch ein anderer Benutzer die Seite beispielsweise eine Zehntelsekunde später auf, kann es durchaus in Ordnung sein, ihm dieselbe Seite wie dem vorherigen Benutzer anzuzeigen.
- Von der Anwendung generierte, personalisierte Seiten – Diese lassen sich nicht sinnvoll im Cache speichern, da sie benutzerspezifisch sind und es unwahrscheinlich ist, dass derselbe Benutzer dieselbe personalisierte Seite zweimal aufruft. Ein Beispiel ist eine E-Commerce-Seite für einen angemeldeten Benutzer; dieselbe Seite kann anderen Benutzern nicht angezeigt werden.
Statische Dateien und nicht personalisierte, von Anwendungen generierte Dateien können zwischengespeichert werden
Microcaching eignet sich für den zweiten oben beschriebenen Seitentyp – anwendungsgenerierte, nicht personalisierte Seiten. „Micro“ bezieht sich auf einen kurzen Zeitraum. Wenn Ihre Website dieselbe Seite mehrmals pro Sekunde generiert, wird die Aktualität der Seite möglicherweise kaum beeinträchtigt, wenn Sie sie eine Sekunde lang im Cache speichern. Dennoch kann dieser kurze Caching-Zeitraum den Anwendungsserver erheblich entlasten, insbesondere bei Lastspitzen. Anstatt während des Cache-Timeout-Zeitraums 10, 20 oder 100 Seiten (mit demselben Inhalt) zu generieren, wird eine bestimmte Seite nur einmal generiert, anschließend im Cache gespeichert und von dort für viele Benutzer bereitgestellt.
Der Effekt grenzt an ein Wunder. Ein Server, der bei der Verarbeitung Dutzender Anfragen pro Sekunde langsam ist, wird ausgesprochen schnell, wenn er nur eine einzige verarbeiten muss. (Zuzüglich natürlich aller personalisierten Seiten.) Unser Kollege Owen Garrett erläutert in einem Blogbeitrag ausführlich die Vorteile von Microcaching und stellt dazu auch Konfigurationscode bereit. Für die wesentliche Änderung – die Einrichtung eines Proxy-Caches mit einem Timeout von einer Sekunde – sind nur wenige Zeilen Konfigurationscode erforderlich.
proxy_cache_path /tmp/cache keys_zone=cache:10m levels=1:2 inactive=600s max_size=100m;server {
proxy_cache cache;
proxy_cache_valid 200 1s;
# ...
}Weitere Beispielkonfigurationen finden Sie in Tyler Hicks‑Wrights Blogbeitrag über Python und uWSGI mit NGINX.
Fazit
In Teil I haben wir Lösungen zur Leistungssteigerung einer Python-Implementierung auf einem einzelnen Server sowie Caching behandelt. Caching kann in einer Einzelserver-Implementierung eingesetzt oder auf einem Reverse-Proxy-Server beziehungsweise einem separaten Cache-Server betrieben werden. (Caching funktioniert auf einem separaten Server besser.) Der nächste Teil, Teil 2, beschreibt Lösungen zur Leistungssteigerung, die zwei oder mehr Server erfordern.
Wenn Sie die erweiterten Funktionen von NGINX Plus für Ihre Anwendung kennenlernen möchten, beispielsweise Support, Live-Aktivitätsüberwachung und spontane Neukonfiguration, starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen.
Über den Autor

Ähnliche Blogbeiträge
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
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
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
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 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
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.