A Beginner’s Guide to Python Tornado

Das Web ist jetzt ein großer Ort. Wir müssen Tausende von Clients gleichzeitig unterstützen, und hier kommt Tornado. Tornado ist ein Python-Web-Framework und eine asynchrone Netzwerkbibliothek, die ursprünglich bei FriendFreed entwickelt wurde.

Tornado verwendet ein nicht-blockierendes Netzwerk-io. Dadurch kann es Tausende von aktiven Serververbindungen verarbeiten. Es ist ein Retter für Anwendungen, bei denen lange Pollings und eine große Anzahl aktiver Verbindungen gepflegt werden.

Tornado ist nicht wie die meisten Python-Frameworks. Es basiert nicht auf WSGI, obwohl es einige Funktionen von WSGI mit dem Modul `tornado.wsgi` unterstützt. Es verwendet ein Ereignisschleifendesign, das die Ausführung von Tornado-Anfragen schneller macht.

Was ist ein synchrones Programm?

Eine Funktion blockiert, führt ihre Berechnungen durch und kehrt zurück, sobald sie fertig ist. Eine Funktion kann aus vielen Gründen blockieren: Netzwerk-E/A, Festplatten-E/A, Mutexe usw.

Die Leistung einer Anwendung hängt davon ab, wie effizient die Anwendung die CPU-Zyklen nutzt, deshalb müssen blockierende Anweisungen/Aufrufe ernst genommen werden. Man denke an Passwort-Hashing-Funktionen wie bcrypt, die von vornherein Hunderte von Millisekunden an CPU-Zeit verbrauchen, weit mehr als ein typischer Netzwerk- oder Plattenzugriff. Da die CPU nicht untätig ist, gibt es keinen Grund, asynchrone Funktionen zu verwenden.

Eine Funktion kann in einem Fall blockierend und in anderen Fällen nicht blockierend sein. Im Zusammenhang mit Tornado betrachten wir im Allgemeinen die Blockierung aufgrund von Netzwerk-E/A und Festplatte, obwohl alle Arten von Blockierung minimiert werden müssen.

Was ist ein asynchrones Programm?

1) Single-Thread-Architektur:

Das bedeutet, dass rechenzentrierte Aufgaben nicht parallel ausgeführt werden können.

2) E/A-Gleichzeitigkeit:

Es kann E/A-Aufgaben an das Betriebssystem übergeben und mit der nächsten Aufgabe fortfahren, um Parallelität zu erreichen.

3) epoll/ kqueue:

Systembezogenes Konstrukt, das es einer Anwendung ermöglicht, Ereignisse auf einem Dateideskriptor oder I/O-spezifische Aufgaben zu erhalten.

4) Ereignisschleife:

Sie verwendet epoll oder kqueue, um zu prüfen, ob ein Ereignis eingetreten ist, und führt einen Callback aus, der auf diese Netzwerkereignisse wartet.

Asynchronous vs Synchronous Web Framework:

Im Falle des synchronen Modells wird jede Anfrage oder Aufgabe an einen Thread oder ein Routing weitergeleitet, und wenn sie abgeschlossen ist, wird das Ergebnis an den Aufrufer übergeben. Hier ist die Verwaltung der Dinge einfach, aber das Erstellen neuer Threads ist zu viel Overhead.

Auf der anderen Seite gibt es in asynchronen Frameworks, wie Node.js, ein Single-Thread-Modell, also sehr wenig Overhead, aber es hat Komplexität.

Stellen wir uns vor, dass Tausende von Anfragen durchkommen und ein Server Ereignisschleifen und Callbacks verwendet. Nun, bis die Anfrage verarbeitet wird, muss er den Zustand dieser Anfrage effizient speichern und verwalten, um das Callback-Ergebnis dem eigentlichen Client zuzuordnen.

Node.js vs Tornado

Die meisten dieser Vergleichspunkte sind an die eigentliche Programmiersprache und nicht an das Framework gebunden:

  • Node.js hat den großen Vorteil, dass alle seine Bibliotheken Async sind. In Python gibt es viele verfügbare Pakete, aber nur sehr wenige davon sind asynchron
  • Da Node.js eine JavaScript-Laufzeitumgebung ist und wir JS sowohl für das Front- als auch für das Backend verwenden können, können Entwickler nur eine Codebasis behalten und dieselbe Hilfsbibliothek nutzen
  • Googles V8-Engine macht Node.js schneller als Tornado. Aber viele Python-Bibliotheken sind in C geschrieben und können schnellere Alternativen sein.

Ein einfaches ‚Hello World‘ Beispiel

CODE: https://gist.github.com/velotiotech/b4d91554b739f2487bf6131ac65ec06d.js

Hinweis: Dieses Beispiel verwendet keine asynchrone Funktion.

Mit dem Modul AsyncHTTPClient können wir REST-Aufrufe asynchron ausführen.

CODE: https://gist.github.com/velotiotech/5fe63eb5fd6cf3af9bf353c2fd3b4ca7.js

Wie Sie sehen können, wird `yield http_client.fetch(url)` als Coroutine ausgeführt.

Komplexes Beispiel für Tornado Async

Schauen Sie sich bitte den Asynchronous Request Handler an.

WebSockets mit Tornado:

Tornado hat ein eingebautes Paket für WebSockets, das leicht mit Coroutines verwendet werden kann, um Gleichzeitigkeit zu erreichen, hier ist ein Beispiel:

CODE: https://gist.github.com/velotiotech/34d0a0e0ecd57818ae1db1697c075777.js

Man kann eine WebSocket-Client-Anwendung verwenden, um sich mit dem Server zu verbinden, die Nachricht kann eine beliebige Ganzzahl sein. Nach der Verarbeitung erhält der Client das Ergebnis, ob die ganze Zahl eine Primzahl ist oder nicht.
Hier ist ein weiteres Beispiel für die aktuellen asynchronen Funktionen von Tornado. Viele werden es ähnlich wie Golangs Goroutine und Channels finden.

In diesem Beispiel können wir Worker starten, die auf die ‚tornado.queue‘ hören. Diese Warteschlange ist asynchron und dem asyncio-Paket sehr ähnlich.

CODE: https://gist.github.com/velotiotech/1477131948ca23879167df0281726d02.js

Fazit

1) Asynchrone Frameworks sind nicht sehr nützlich, wenn die meisten Berechnungen CPU-zentrisch und nicht I/O-zentrisch sind.

2) Aufgrund eines Single-Thread-pro-Core-Modells und einer Ereignisschleife kann es Tausende von aktiven Client-Verbindungen verwalten.

3) Viele sagen, Django sei zu groß, Flask sei zu klein und Tornado sei genau richtig:

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.