BLOG | NGINX

Maximieren der Python-Leistung mit NGINX, Teil 1: Web-Serving und Caching

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Floyd Smith Miniaturbild
Floyd Smith
Veröffentlicht am 31. März 2016

Einführung – So wird NGINX mit Python verwendet

Python ist dafür bekannt, dass es einfach und unterhaltsam zu verwenden ist, die Softwareentwicklung vereinfacht und eine Laufzeitleistung aufweist, die andere Skriptsprachen übertreffen soll. (Obwohl die neueste PHP-Version, PHP 7, Python durchaus Konkurrenz machen könnte.)

Jeder möchte, dass seine Website und Anwendung schneller laufen. Außerdem ist jede Website mit zunehmendem Datenverkehr oder starken Datenverkehrsspitzen anfällig für Leistungsprobleme und Ausfallzeiten, die oft in den ungünstigsten Zeiten, also den geschäftigsten Zeiten, auftreten. Zudem leiden fast alle Websites unter Leistungsproblemen und Ausfallzeiten, unabhängig davon, ob das Datenverkehrsaufkommen stetig steigt oder es zu starken Nutzungsspitzen kommt.

Hier kommen NGINX und NGINX Plus ins Spiel. Sie verbessern die Website-Leistung auf drei verschiedene Arten:

  1. Als Webserver wurde NGINX ursprünglich entwickelt, um das C10K-Problem zu lösen, das heißt, um problemlos 10.000 oder mehr gleichzeitige Verbindungen zu unterstützen. Wenn Sie NGINX als Webserver für Ihre Python-App verwenden, wird Ihre Website schneller, selbst bei geringem Datenverkehr. Bei vielen Tausend Benutzern ist mit einer deutlich höheren Leistung sowie weniger Abstürzen und Ausfallzeiten praktisch gerechnet. Sie können auf Ihrem NGINX-Webserver auch statisches Datei-Caching oder Mikrocaching durchführen. Beides funktioniert jedoch besser, wenn es auf einem separaten NGINX-Reverse-Proxy-Server ausgeführt wird (siehe nächsten Absatz).
  2. Als Reverse-Proxy-Server – Sie können NGINX als Reverse-Proxy-Server vor Ihr aktuelles Anwendungsserver-Setup „einbinden“. NGINX ist mit dem Web verbunden und leitet Anfragen an Ihren Anwendungsserver weiter. Dieser „einzige seltsame Trick“ sorgt dafür, dass Ihre Website schneller läuft, reduziert Ausfallzeiten, verbraucht weniger Serverressourcen und verbessert die Sicherheit. Sie können auch statische Dateien auf dem Reverse-Proxy-Server zwischenspeichern (sehr effizient), Mikrocaching von dynamischen Inhalten hinzufügen, um die Belastung der Anwendung selbst zu verringern, und vieles mehr.
  3. Als Lastenausgleich für mehrere Anwendungsserver – Beginnen Sie mit der Bereitstellung eines Reverse-Proxy-Servers. Skalieren Sie dann, indem Sie mehrere Anwendungsserver parallel ausführen und den Datenverkehr mithilfe von NGINX oder NGINX Plus zwischen ihnen verteilen. Mit dieser Art der Bereitstellung können Sie die Leistung Ihrer Website problemlos entsprechend den Verkehrsanforderungen skalieren und so die Zuverlässigkeit und Verfügbarkeit verbessern. Wenn eine bestimmte Benutzersitzung auf demselben Server bleiben muss, konfigurieren Sie den Load Balancer so, dass er die Sitzungspersistenz unterstützt.

NGINX und NGINX Plus bieten Vorteile, egal ob Sie sie als Webserver für Ihre Python-App, als Reverse-Proxy-Server, als Load Balancer oder für alle drei Zwecke verwenden.

In diesem ersten Artikel einer zweiteiligen Serie beschreiben wir fünf Tipps zur Verbesserung der Leistung Ihrer Python-Apps, einschließlich der Verwendung von NGINX und NGINX Plus als Webserver, wie Sie das Caching statischer Dateien und das Mikrocaching anwendungsgenerierter Dateien implementieren. In Teil 2 beschreiben wir, wie Sie NGINX und NGINX Plus als Reverse-Proxy-Server und als Load Balancer für mehrere Anwendungsserver verwenden.

Tipp 1 – Leistungsengpässe in Python finden

Es gibt zwei sehr unterschiedliche Bedingungen, unter denen die Leistung Ihrer Python-Anwendung eine Rolle spielt: erstens bei einer alltäglichen, „angemessenen“ Benutzerzahl und zweitens bei hoher Belastung. Viele Websitebesitzer machen sich zu wenig Gedanken über die Leistung bei geringer Belastung, obwohl ihnen – unserer bescheidenen Meinung nach – jede Zehntelsekunde hinsichtlich der Reaktionszeit ins Schwitzen kommen sollte. Die Reaktionszeiten um Millisekunden zu verkürzen ist eine schwierige und undankbare Aufgabe, macht die Benutzer jedoch zufriedener und führt zu besseren Geschäftsergebnissen.

Dieser Blogbeitrag und der dazugehörige Teil 2 konzentrieren sich jedoch eher auf das Szenario, das allen Sorgen bereitet: Leistungsprobleme, die auftreten, wenn eine Site stark ausgelastet ist, wie etwa erhebliche Leistungseinbußen und Abstürze. Darüber hinaus ahmen viele Hackerangriffe die Auswirkungen eines plötzlichen Anstiegs der Benutzerzahlen nach. Die Verbesserung der Site-Leistung ist daher häufig auch ein wichtiger Schritt im Kampf gegen Angriffe .

Bei einem System, das jedem Benutzer eine bestimmte Speichermenge zuweist, wie z. B. dem Apache HTTP Server, führt das Hinzufügen von Benutzern dazu, dass der physische Speicher überlastet wird, da immer mehr Benutzer hinzukommen. Der Server beginnt, Daten auf die Festplatte auszulagern, die Leistung sinkt rapide und es kommt zu schlechter Performance und Abstürzen. Die in diesem Blogbeitrag beschriebene Umstellung auf NGINX trägt zur Lösung dieses Problems bei.

Python ist besonders anfällig für speicherbezogene Leistungsprobleme, da es im Allgemeinen mehr Speicher zum Erfüllen seiner Aufgaben verwendet als andere Skriptsprachen (und sie daher schneller ausführt). Wenn also sonst alle anderen Bedingungen gleich bleiben, kann Ihre Python-basierte App bei einer geringeren Benutzerlast „zusammenbrechen“ als eine App, die in einer anderen Sprache geschrieben ist.

Durch die Optimierung Ihrer App können Sie etwas Abhilfe schaffen, aber das ist normalerweise weder die beste noch die schnellste Möglichkeit, verkehrsbedingte Leistungsprobleme der Website zu lösen. Die Schritte in diesem Blogbeitrag und dem dazugehörigen Teil 2 stellen die beste und schnellste Möglichkeit dar, verkehrsbedingte Leistungsprobleme zu beheben. Nachdem Sie die hier angegebenen Schritte ausgeführt haben, gehen Sie auf jeden Fall zurück und verbessern Sie Ihre App oder schreiben Sie sie neu, um eine Microservices-Architektur zu verwenden.

Tipp 2 – Wählen Sie die Bereitstellung auf einem oder mehreren Servern

Kleine Websites funktionieren gut, wenn sie auf einem einzelnen Server bereitgestellt werden. Große Websites erfordern mehrere Server. Wenn Sie sich jedoch in der Grauzone dazwischen befinden – oder Ihre Site von einer kleinen zu einer großen Site heranwächst –, müssen Sie einige interessante Entscheidungen treffen.

Bei einer Bereitstellung mit nur einem Server besteht ein erhebliches Risiko, wenn es zu Verkehrsspitzen oder einem schnellen Anstieg des Gesamtverkehrs kommt. Ihre Skalierbarkeit ist eingeschränkt. Zu den möglichen Lösungen gehören die Verbesserung Ihrer App, die Umstellung Ihres Webservers auf NGINX, die Anschaffung eines größeren und schnelleren Servers oder die Auslagerung des Speichers auf ein Content Delivery Network (CDN). Die Umsetzung jeder dieser Optionen nimmt Zeit in Anspruch, ist mit Kosten verbunden und birgt das Risiko, dass bei der Umsetzung Fehler oder Probleme auftreten.

Außerdem hat Ihre Site bei der Bereitstellung auf einem Einzelserver per Definition einen einzigen Ausfallpunkt – und für viele Probleme, die Ihre Site offline nehmen können, gibt es keine schnellen oder einfachen Lösungen.

NGINX und Python arbeiten zusammen, um Leistung durch die Funktionen von NGINX in den Bereichen Web-Serving, Lastausgleich und Caching zu liefern
„NGINX vor“ Anwendungsservern ablegen

Wenn Sie Ihren Server in einer Einzelserverbereitstellung auf NGINX umstellen, können Sie frei zwischen NGINX Open Source und NGINX Plus wählen. NGINX Plus umfasst Support auf Unternehmensniveau und zusätzliche Funktionen . Einige der zusätzlichen Funktionen, beispielsweise die Live-Aktivitätsüberwachung , sind für die Bereitstellung eines Einzelservers relevant, und andere, beispielsweise Lastausgleich und Sitzungspersistenz , kommen zum Tragen, wenn Sie NGINX Plus als Reverse-Proxy-Server in einer Bereitstellung mit mehreren Servern verwenden.

Alles in allem ist die Bereitstellung auf einem einzelnen Server mit gewissen Risiken verbunden, es sei denn, Sie sind sicher, dass Ihre Site auch in Zukunft klein bleiben wird und Ausfallzeiten kein großes Problem darstellen. Die Bereitstellung auf mehreren Servern ist nahezu beliebig skalierbar – einzelne Fehlerquellen können beseitigt werden und die Leistung lässt sich beliebig gestalten, wobei die Kapazität schnell erweitert werden kann.

Tipp 3 – Ändern Sie Ihren Webserver in NGINX

In den frühen Tagen des Web war der Name „Apache“ ein Synonym für „Webserver“. Aber NGINX wurde Anfang der 2000er Jahre entwickelt und erfreut sich stetig wachsender Beliebtheit; auf den 1.000, 10.000, 100.000 und [ngx_snippet name='proportion-top-sites'] der Welt ist es bereits der Webserver Nr. 1.

NGINX wurde entwickelt, um das C10K-Problem zu lösen, also mehr als 10.000 gleichzeitige Verbindungen innerhalb eines bestimmten Speicherbudgets zu verarbeiten. Andere Webserver benötigen für jede Verbindung einen bestimmten Speicherblock , sodass ihnen der physische Speicher ausgeht und sie langsamer werden oder abstürzen, wenn Tausende von Benutzern gleichzeitig auf eine Site zugreifen möchten. NGINX verarbeitet jede Anfrage separat und skaliert problemlos auf eine viel größere Anzahl von Benutzern. (Es eignet sich auch hervorragend für weitere Zwecke, wie wir weiter unten beschreiben.)

Unten wird ein Überblick über die Architektur von NGINX angezeigt.

Anleitung zur Konfiguration der Architektur für Python unter Verwendung von NGINX-Funktionen für Web-Serving, Lastenausgleich und Caching
NGINX-Architektur, aus „Die Architektur von Open-Source-Anwendungen“, Band II

Im Diagramm passt ein Python-Anwendungsserver in den Anwendungsserverblock im Backend und wird angezeigt, wie er von FastCGI aufgerufen wird. NGINX „weiß“ nicht, wie Python ausgeführt wird, und benötigt daher ein Gateway zu einer Umgebung, die es kann. FastCGI ist eine weit verbreitete 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 Multithread- und Multiprozessumgebungen und lässt sich daher für alle in diesem Blogbeitrag genannten Bereitstellungsoptionen gut skalieren.

Wenn Sie zu NGINX als Ihrem Webserver wechseln, gibt es viel Unterstützung für die erforderlichen Schritte:

Dieser Codeausschnitt zeigt, wie Sie NGINX für die Verwendung mit uWSGI konfigurieren können – in diesem Fall ein Projekt, das das Python-Framework Django verwendet:

http { # ...
Upstream django {
Server 127.0.0.1:29000;
}

Server {
Listen 80;
Servername myapp.example.com;

Root /var/www/myapp/html;

Standort / {
Index index.html;
}

Standort /static/ {
Alias /var/django/projects/myapp/static/;
}

Standort /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 – Implementieren Sie ein statisches Datei-Caching

Beim Zwischenspeichern statischer Inhalte wird eine Kopie von Dateien, die sich nicht so oft ändern – also beispielsweise alle paar Stunden oder nie – an einem anderen Ort als dem Anwendungsserver gespeichert. Ein typisches Beispiel für statischen Inhalt ist ein JPEG-Bild, das als Teil einer Webseite angezeigt wird.

Das Zwischenspeichern statischer Dateien ist eine gängige Methode zur Verbesserung der Anwendungsleistung und geschieht tatsächlich auf mehreren Ebenen:

  • Im Browser des Benutzers
  • Bei Internetanbietern auf mehreren Ebenen – vom internen Netzwerk eines Unternehmens bis zum Internet Service Provider (ISP)
  • Auf einem Webserver, wie wir hier beschreiben werden

Die Implementierung der statischen Dateizwischenspeicherung auf dem Webserver bietet zwei Vorteile:

  • Schnellere Bereitstellung für den Benutzer – NGINX ist für das Zwischenspeichern statischer Dateien optimiert und führt Anfragen nach statischen Inhalten viel schneller aus als ein Anwendungsserver.
  • Reduzierte Belastung des Anwendungsservers – Der Anwendungsserver sieht nicht einmal Anforderungen für zwischengespeicherte statische Dateien, da der Webserver diese erfüllt.

Das Zwischenspeichern statischer Dateien funktioniert bei einer Einzelserverimplementierung gut, die zugrunde liegende Hardware wird jedoch weiterhin vom Webserver und vom Anwendungsserver gemeinsam genutzt. Wenn die Hardware des Webservers damit beschäftigt ist, eine zwischengespeicherte Datei abzurufen – selbst wenn dies sehr effizient geschieht –, stehen der Anwendung diese Hardwareressourcen nicht zur Verfügung, was sie möglicherweise etwas verlangsamt.

Um das Browser-Caching zu unterstützen, legen Sie die HTTP-Header für statische Dateien richtig fest. Berücksichtigen Sie dabei den HTTP- Cache-Control- Header (und insbesondere seine Max-Age -Einstellung), den Expires- Header und die Entity- Tags. Eine gute Einführung in das Thema finden Sie unter „Verwenden von NGINX und NGINX Plus als Anwendungsgateway mit uWSGI und Django“ im NGINX Plus-Administratorhandbuch.

Der folgende Code konfiguriert NGINX so, dass statische Dateien zwischengespeichert werden, darunter JPEG-Dateien, GIFs, PNG-Dateien, MP4-Videodateien, Powerpoint-Dateien und viele andere. Ersetzen Sie www.example.com durch die URL Ihres Webservers.

server { # ersetzen Sie die URL Ihres Webservers durch „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;
# ersetzen Sie den Socket oder die Adresse und den Port Ihres Python-Servers
fastcgi_pass unix:/var/run/php5-fpm.sock;
#fastcgi_pass 127.0.0.1:9000;
} 

Standort ~* .(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)$ {
läuft max ab;
log_not_found aus;
access_log aus;
}
}

Tipp 5 – Implementieren Sie Microcaching

Microcaching bietet enorme Möglichkeiten zur Leistungssteigerung auf Anwendungsservern, auf denen Python, PHP und andere Sprachen ausgeführt werden. Für Caching-Zwecke gibt es drei Arten von Webseiten:

  • Statische Dateien – Diese können zwischengespeichert werden, wie in Tipp 4 beschrieben.
  • Von der Anwendung generierte, nicht personalisierte Seiten – Es ist normalerweise nicht sinnvoll, diese zwischenzuspeichern, da sie aktuell sein müssen. Ein Beispiel ist eine Seite, die einem E-Commerce-Benutzer bereitgestellt wird, der nicht angemeldet ist (siehe nächster Punkt). Die verfügbaren Produkte, empfohlenen ähnlichen Produkte usw. können sich ständig ändern. Daher ist es wichtig, eine aktuelle Seite bereitzustellen. Kommt jedoch beispielsweise eine Zehntelsekunde später ein anderer Benutzer vorbei, ist es möglicherweise ausreichend, ihm dieselbe Seite wie dem vorherigen Benutzer anzuzeigen.
  • Von der Anwendung erstellte, personalisierte Seiten – Diese können nicht sinnvoll zwischengespeichert werden, da sie benutzerspezifisch sind und es unwahrscheinlich ist, dass derselbe Benutzer dieselbe personalisierte Seite zweimal sieht. Ein Beispiel ist eine E-Commerce-Seite für einen angemeldeten Benutzer. Die gleiche Seite kann anderen Benutzern nicht angezeigt werden.
Mikro-Caching mit NGINX
Statische Dateien und nicht personalisierte, von der Anwendung generierte Dateien können zwischengespeichert werden

Microcaching ist für den zweiten oben beschriebenen Seitentyp nützlich – anwendungsgenerierte, nicht personalisierte Seiten. „Mikro“ bezieht sich auf einen kurzen Zeitraum. Wenn Ihre Site dieselbe Seite mehrmals pro Sekunde generiert, kann es die Aktualität der Seite nicht wesentlich beeinträchtigen, wenn Sie sie für eine Sekunde zwischenspeichern. Doch dieser kurze Caching-Zeitraum kann den Anwendungsserver enorm entlasten, insbesondere bei Verkehrsspitzen. 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 zwischengespeichert und aus dem Cache vielen Nutzern bereitgestellt.

Die Wirkung ist beinahe wundersam. Ein Server, der bei der Verarbeitung von Dutzenden von Anfragen pro Sekunde langsam ist, wird bei der Verarbeitung von genau einer Anfrage ziemlich schnell. (Plus natürlich alle personalisierten Seiten.) Unser eigener Owen Garrett hat einen Blog-Beitrag verfasst, der die Vorteile von Microcaching mit Konfigurationscode näher erläutert. Die zentrale Änderung, das Einrichten eines Proxy-Cache mit einem Timeout von einer Sekunde, erfordert nur wenige Zeilen Konfigurationscode.

Proxy-Cache-Pfad /tmp/cache Schlüsselzone=Cache:10m Ebenen=1:2 inaktiv=600s max_size=100m;Server {
Proxy-Cache Cache;
Proxy-Cache_gültig 200 1s;
# ...
}

Weitere Beispielkonfigurationen finden Sie im Blog von Tyler Hicks-Wright über Python und uWSGI mit NGINX .

Abschluss

In Teil I haben wir Lösungen zur Leistungssteigerung einer Single-Server-Python-Implementierung sowie zum Caching besprochen, die auf einer Single-Server-Implementierung eingesetzt oder auf einem Reverse-Proxy-Server oder einem separaten Caching-Server ausgeführt werden können. (Das Caching funktioniert auf einem separaten Server besser.) Der nächste Teil, Teil 2 , beschreibt Leistungslösungen, die zwei oder mehr Server erfordern.

Wenn Sie die erweiterten Funktionen von NGINX Plus für Ihre Anwendung erkunden möchten, z. B. Support, Live-Aktivitätsüberwachung und Neukonfiguration im laufenden Betrieb, 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."