Laden Sie die neueste Version für Mac OS X Downloaden Sie die neueste Quellversion Download der neuesten Version für Windows Downloaden Sie die neuesten Versionen von Python OpenPGP Public Keys Quelle und binäre ausführbare Dateien werden vom Release Manager mit ihrem OpenPGP-Schlüssel signiert. Die Release-Manager und Binär-Builder seit Python 2.3 wurden: Hinweis: Barrys-Schlüssel-ID A74B06BF wird verwendet, um die Python 2.6.8 und 2.6.9 Releases zu signieren. Seine Schlüssel-ID EA5BBD71 wurde verwendet, um alle anderen Python 2.6- und 3.0-Versionen zu signieren. Seine Schlüssel-ID ED9D77D5 ist ein v3-Schlüssel und wurde verwendet, um ältere Releases zu signieren. Sie können die öffentlichen Schlüssel des öffentlichen Verwalters importieren, indem Sie entweder die öffentliche Schlüsseldatei von hier herunterladen und dann ausführen oder indem Sie die einzelnen Schlüssel direkt aus dem Keyserver-Netzwerk abrufen, indem Sie diesen Befehl ausführen: Auf den versionsspezifischen Download-Seiten sollten Sie einen Link zu sehen Sowohl die herunterladbare Datei als auch eine freistehende Signaturdatei. Um die Echtheit des Downloads zu überprüfen, packen Sie beide Dateien und führen Sie diesen Befehl aus: Beachten Sie, dass Sie den Namen der Signaturdatei verwenden müssen und Sie sollten die für den Download passende Version verwenden. (Diese Anleitung richtet sich an GnuPG - und Unix-Befehlszeilenbenutzer.) Beiträge zu anderen Plattformen und OpenPGP-Anwendungen sind willkommen.) Weitere nützliche Gegenstände Auf der Suche nach Drittanbieter-Python-Modulen. Der Paketindex hat viele davon. Sie können die Standarddokumentation online ansehen oder in HTML, PostScript, PDF und anderen Formaten herunterladen. Siehe die Seite "Hauptdokumentation". Informationen zu den Tools zum Entpacken von Archivdateien finden Sie auf python. org. Tipp. Auch wenn Sie eine fertige Binärdatei für Ihre Plattform herunterladen, ist es sinnvoll, auch die Quelle herunterzuladen. Auf diese Weise können Sie die Standardbibliothek (das Unterverzeichnis Lib) und die Standardsammlungen von Demos (Demo) und Tools (Tools) durchsuchen, die mitgeliefert werden. Theres viel, das Sie von der Quelle lernen können Es gibt auch eine Ansammlung Emacs Pakete, die das Emacsing Pythoneer nützlich finden könnte. Dies beinhaltet große Modi für die Bearbeitung von Python, C, C, Java, etc. Python-Debugger-Schnittstellen und vieles mehr. Die meisten Pakete sind mit Emacs und XEmacs kompatibel. Wollen Sie beitragen Sehen Sie sich die Python-Entwickler-Guide, um zu erfahren, wie Python-Entwicklung verwaltet wird. Nicholas Pil Benchmark von Python WSGI-Servern Es ist eine Weile seit der Sockel-Benchmark von Asynchronous Server. Dieser Benchmark betrachtete die Rohe-Socket-Performance verschiedener Frameworks, die durch eine regelmäßige HTTP-Anforderung an den TCP-Server benchmarkiert wurde. Der Server selbst war dumm und nicht wirklich verstehen, die Header, die zu senden. In diesem Benchmark werde ich untersuchen, wie verschiedene WSGI-Server bei genau dieser Aufgabe die Abwicklung einer vollständigen HTTP-Anforderung durchführen. Ich sollte sofort mit einem Wort der Vorsicht beginnen. Ich versuchte mein Bestes, einen objektiven Benchmark der verschiedenen WSGI-Server zu präsentieren. Und ich glaube wirklich, dass eine Benchmark eine der besten Methoden ist, um einen unvoreingenommenen Vergleich zu präsentieren. Allerdings misst ein Benchmark die Performance auf einer sehr spezifischen Domain und es könnte sehr gut sein, dass diese Domain zu bestimmten Frameworks geneigt ist. Aber, wenn wir das im Auge behalten, können wir tatsächlich einige Messungen hinter all jenen 8216faster als8217 oder 8216lighter als8217 behaupten, die Sie überall finden werden. Meiner Meinung nach sind solche Vergleichsansprüche ohne detaillierte Beschreibung, wie sie gemessen werden, schlechter als eine voreingenommene, aber detaillierte Benchmark. Der spezifische Bereich dieses Benchmarks ist wiederum der PingPong-Benchmark, wie er früher in meinem Async Socket Benchmark verwendet wurde. Allerdings gibt es einige Unterschiede: Wir werden mehrere Anfragen über eine einzige Verbindung, wenn möglich, durch eine HTTP 1.1-Keepalive-Verbindung Es ist eine verteilte Benchmark mit mehreren Clients Wir verwenden eine identische WSGI-Anwendung für alle Server anstelle von speziell gestalteten Code Um die Antwort zurückzugeben Wir erwarten, dass der Server unsere HTTP-Anforderung versteht und mit den korrekten Fehlercodes antwortet Dieser Benchmark ist ein konzeptionell einfacher und Sie könnten behaupten, dass dies nicht für die meisten gängigen Webanwendungen repräsentativ ist, die sich stark auf die Blockierung von Datenbankverbindungen verlassen. Ich bin damit einverstanden, da dies meistens der Fall ist. Allerdings wird der Push in HTML58217s Websockets und hoch interaktive Web-Anwendungen Server, die in der Lage, viele gleichzeitige Verbindungen mit geringer Latenz zu bedienen sind. Der Benchmark Wir führen die folgende WSGI-Anwendung 8216pong. py8217 auf allen Servern aus. Wir werden auch tune sowohl Client und Server, indem Sie die folgenden Befehle. Dies ermöglicht dem Server, LOTS von gleichzeitigen Verbindungen zu öffnen. echo 822010152 655358243 gt procsysnetipv4iplocalportrange sysctl - w fs. file-max128000 sysctl - w net. ipv4.tcpkeepalivetime300 sysctl - w net. core. somaxconn250000 sysctl - w net. ipv4.tcpmaxsynbacklog2500 sysctl - w net. core. netdevmaxbacklog2500 ulimit - n 10240 Die Server ist eine virtuelle Maschine mit nur einem zugeordneten Prozessor. Ich habe die Menge der verfügbaren Prozessoren explizit begrenzt, um sicherzustellen, dass es ein fairer Vergleich ist. Ob der Server skaliert über mehrere Prozessoren ist eine interessante und nützliche Funktion, aber das ist nicht etwas, was ich in diesem Benchmark Maßnahme. Der Grund dafür ist, dass es schwierig ist, Ihre Anwendung auf mehrere Prozessoren zu skalieren, indem Sie einen Reverse-Proxy und mehrere Serverprozesse verwenden (dies kann sogar für spezielle Anwendungen wie Spawning oder Grainbows verwaltet werden). Der Server und die Clients führen Debian Lenny mit Python 2.6.4 auf der amd64-Architektur aus. Ich habe dafür gesorgt, dass alle WSGI-Server einen Backlog-Satz von mindestens 500 haben und dass (connectionerror) - Logging deaktiviert ist, wenn dies nicht direkt von der aufrufbaren I-Version der Bibliothek möglich war. Der Server und die Clients haben 1GB RAM. Ich benchmarked die HTTP1.0-Anforderungsrate aller Server und die HTTP1.1-Anfragerate auf der Teilmenge von Servern, die Pipeline mehrere Anfragen über eine einzelne Verbindung unterstützen. Während der Mangel an HTTP 1.1 keepalive Unterstützung ist höchstwahrscheinlich ein Nicht-Problem in aktuellen Einsatzsituationen Ich erwarte, dass es ein wichtiges Merkmal in Anwendungen, die stark von Verbindungen mit geringer Latenz abhängig sind. Sie sollten über Comet-Stil Web-Anwendungen oder Anwendungen, die HTML5 Webseiten verwenden denken. Ich kategorisiere einen Bediener als HTTP1.1, der durch sein Verhalten, nicht durch seine Spezifikt. Zum Beispiel der Paster-Server sagt, dass es einige Unterstützung für HTTP 1.1 Keep Alives, aber ich war nicht in der Lage, mehrere Anfragen Pipeline. Dieser Fehler wurde möglicherweise für diese Situation relevant und kann für einige der anderen 8220HTTP 1.0 Servers8221 gelten. Der Benchmark wird ausgeführt, indem ein neu kompiliertes httperf (das die statische kompilierte Dateigröße im debian-Paket umbringt) auf 3 verschiedenen speziell eingerichteten Client-Rechnern ausgeführt wird. Um die verschiedenen Anforderungsraten zu initialisieren und die Ergebnisse zusammenzufassen, verwende ich ein Tool namens autobench. Hinweis: Dies ist nicht ApacheBench (ab). Der Befehl zum Benchmark HTTP1.0 WSGI Server ist: httperf 8211hog 8211timeout5 8211client01 8211servertsung1 8211port8000 8211uri 8211rate ltRATEgt 8211send-buffer4096 8211recv-buffer16384 8211num-conns400 8211num-Anrufe1 Und der Befehl für HTTP1.1 WSGI Server ist: httperf 8211hog 8211timeout5 8211client01 8211servertsung1 8211port8000 8211uri 8211rate ltRATEgt 8211send-buffer4096 8211recv-buffer16384 8211num-conns400 8211num-calls10 Die Teilnehmer Python ist wirklich reich mit WSGI Server, ich habe eine Auswahl an verschiedenen Servern hergestellt, die unten aufgeführt sind. Die meisten Informationen in dieser Tabelle sollten ziemlich einfach sein, ich spezifiziere die Version, die benchmarked ist und ob der Bediener zu HTTP 1.1 gefunden worden ist oder nicht. Der Geschmack des Servers spezifiziert das Parallelitätsmodell, das der Server nutzt und ich identifiziere 3 verschiedene Aromen: Prozessor-Thread-Modell Das pt-Modell ist der häufigste Geschmack. Jede Anforderung läuft in einem eigenen, sauber getrennten Thread. Eine Sperranforderung (wie z. B. ein synchroner Datenbankaufruf oder ein Funktionsaufruf in einer C-Erweiterung) hat keinen Einfluss auf andere Anforderungen. Dies ist praktisch, da Sie nicht brauchen, um darüber zu kümmern, wie alles umgesetzt wird, aber es kommt zu einem Preis. Die maximale Anzahl von gleichzeitigen Verbindungen ist durch Ihre Anzahl von Arbeitern oder Threads begrenzt, und dies ist bekannt, dass sie schlecht skalieren, wenn Sie die Notwendigkeit für viele gleichzeitige Benutzer haben. Callback Generator-Modell Das Callbackgenerator-Modell behandelt mehrere gleichzeitige Verbindungen in einem einzigen Thread, wodurch die Thread-Barriere entfernt wird. Ein einziger blockierender Anruf blockiert jedoch die gesamte Ereignisschleife und muss verhindert werden. Die Server, die diesen Geschmack haben, stellen gewöhnlich einen Threadpool zur Verfügung, um blockierende Aufrufe in ihrem asynchronen Framework zu integrieren oder alternative nicht blockierende Datenbankverbindungen bereitzustellen. Um eine Strömungssteuerung zu ermöglichen, verwendet dieser Geschmack Rückrufe oder Generatoren. Einige denken, dass dies eine schöne Art und Weise, um eine Form der Veranstaltung getriebenen Programmierung andere denken, dass es Schlange Grube, die schnell ändert sich Ihren sauberen Code zu einem verschränkten Durcheinander von Rückrufen oder Ertragserklärungen. Der leichte Geschmack benutzt Greenlets, um Gleichzeitigkeit zur Verfügung zu stellen. Dies funktioniert auch durch die Bereitstellung von Parallelität aus einem einzigen Thread, aber in einer weniger aufdringlichen Weise dann mit dem Callbacks oder Generator Ansatz. Aber natürlich muss man vorsichtig sein, um Verbindungen zu sperren, da dies die Ereignisschleife stoppt. Eventlet und Gevent können das Sockelmodul monkeypatch verhindern, damit es blockiert, wenn Sie einen reinen Python-Datenbank-Connector verwenden, sollte dies nie die Schleife blockieren. Concurrence stellt einen asynchronen Datenbankadapter zur Verfügung. Die Umsetzung Besonderheiten für jeden WSGI Server Rubin könnten mit allen Arten von Rockstar Programmierer voll sein (was auch immer das bedeuten mag), aber wenn ich nominieren müssen nur ein Python-Programmierer mit irgendeiner Art von 8216rockstar award8217 ich würde auf jeden Fall nominieren Chad Whitacre. Es ist nicht nur die großen Werkzeuge, die er Testosteron, Aspen, Stephane. Aber meistens, wie er sie mit den meisten ehrfürchtigen screencasts versieht, die ich überhaupt gesehen habe. Sowieso ist Aspen ein ordentlicher kleiner Webserver, der auch in der Lage ist, WSGI Anwendungen zu dienen. Es kann einfach installiert werden mit 8216pip installieren aspen8217 und verwendet eine spezielle Verzeichnis-Struktur für die Konfiguration und wenn Sie mehr Informationen Ich werde Sie auf seine Screencasts Punkt. CherryPy ist eigentlich ein Objekt orientiert Python-Framework, sondern verfügt über einen ausgezeichneten WSGI-Server. Die Installation kann mit einem einfachen 8216pip install cherrypy8217 erfolgen. Ich lief das folgende Skript, um die Leistung des WSGI-Servers auszuprobieren: Der Code, um Cogen eine WSGI-Anwendung ausführen zu lassen, lautet wie folgt: Concurrence Concurrence ist ein asynchrones Framework, das von Hyves entwickelt wurde (Ich habe die neueste stabile Version 1.4.13), feuerte ich die Pong-Anwendung wie folgt: Eventlet ist ein voll ausgestattetes asynchrones Framework, das auch WSGI-Server-Funktionalität bietet. Es ist in Entwicklung von Linden Labs (Hersteller von Second Life). Zum Ausführen der Anwendung verwendete ich den folgenden Code: FAPWS3 ist ein WSGI-Server, der um die LibEV-Bibliothek herum aufgebaut wird (ich verwendete Version 3.43-1.1). Wenn LibEV installiert ist, kann FAPWS problemlos mit pip installiert werden. Die Philosophie hinter FAPWS3 ist es, der einfachste und schnellste Webserver zu bleiben. Das Skript, das ich verwendet, um die WSGI-Anwendung zu starten, ist wie folgt: Gevent ist eines der besten Async Frameworks in meinem vorherigen Sockel-Benchmark. Gevent erweitert Libevent und nutzt seine HTTP-Server-Funktionalität ausgiebig. Zur Installation von Gevent benötigen Sie Libevent installiert, nach dem Sie in Gevent mit PIP ziehen können. Der obige Code wird die Pong-Anwendung ohne Laichen ein Greenlet auf jede Anfrage. Wenn Sie das Argument 8217spawnNone8217 verlassen, wird Gevent ein Greenlet für jede neue Anforderung erzeugen. Gunicorn steht für 8216Green Unicorn8217, jeder weiß, dass ein Einhorn eine Mischung aus dem ehrfürchtigen narwhal und dem ausgezeichneten Pony ist, das das Grün jedoch nichts hat, mit den großen Greenlets zu tun, da es wirklich ein Gewindegeschmack hat. Die Installation ist einfach und kann mit einem einfachen erfolgen 8216pip installieren gunicorn8217 Gunicorn bietet Ihnen einen einfachen Befehl wsgi Anwendungen ausführen, alles, was ich tun musste, war: gunicorn - b: 8000 - w 1 Tennis: Anwendung Update: Ich hatte einige Vorschläge in Der Kommentarabschnitt, der einen einzelnen Arbeiter benutzt und eine Klientverbindung mit dem nackten Bediener hat, ist nicht die korrekte Weise, mit Gunicorn zu arbeiten. So nahm ich ihre Vorschläge und zog Gunicorn hinter NGINX und erhöht die Anzahl der Arbeiter auf die vorgeschlagene Anzahl der Arbeiter, 2N1, wobei N ist 1, die 3 macht. Das Ergebnis davon ist in den Grafiken als gunicorn-3w dargestellt. Der Run Gunicorn mit mehr Arbeitern kann wie getan werden: gunicorn - b unix: varnginxuwsgi. sock - w 3 pong: Anwendung MagnumPy muss der Server mit dem tollsten Namen sein. Dies ist noch ein sehr junges Projekt, aber seine Homepage macht einige starke Aussagen über seine Leistung, so ist es lohnt sich auszuprobieren. Es fühlt sich nicht so poliert wie die anderen Teilnehmer und Installation im Grunde treibt die 8216magnum8217 Verzeichnis auf Ihrem PYTHONPATH bearbeiten 8216.magnumconfig. py8217 nach dem Sie den Server, indem Sie 8216.magnumserve. py start8217 ModWSGI starten kann, ist der Nachfolger von Mod_python es Können Sie problemlos Python-Code mit dem Apache-Server zu integrieren. Meine erste Python-Web-App Erfahrung war mit modpython und PSP-Vorlagen, WSGI und coole Frameworks wie Pylonen haben wirklich das Leben viel einfacher. ModWSGI ist eine großartige Möglichkeit, Ihre Anwendung schnell einzusetzen. Installieren 8216ModWSGI8217 ist mit den meisten Linux-Distributionen wirklich einfach. Zum Beispiel: aptitude install libapache2-mod-wsgi Ist alles, was Sie tun müssen, um eine unberührte Debian-Distribution zu einem funktionierenden Apache-Server (MPM-Worker) mit ModWSGI aktiviert. Um Apache auf Ihre WSGI-Anwendung zu verweisen, fügen Sie einfach eine einzige Zeile zu 8216etcapache2httpd. conf8217 hinzu: Das Problem ist, dass die meisten Leute bereits Apache installiert haben und dass sie es für Schauder-Bedienung von PHP verwenden. PHP ist nicht threadsicher, was bedeutet, dass Sie gezwungen sind, einen vor-forking Apache-Server zu verwenden. In diesem Benchmark verwende ich die Thread-Apache-Version und verwende modwsgi im eingebetteten Modus (da es mir die beste Leistung gab). Ich deaktiviert alle unnötigen Module und konfiguriert Apache, um mir einen einzigen Worker, viele Threads und deaktiviert Protokollierung (Hinweis: Ich versuchte verschiedene Einstellungen): Der Paster Webserver ist der Webserver mit Python Paste ist es Pylons Standard-Webserver. Sie können eine WSGI-Anwendung wie folgt ausführen: Tornado ist der nicht blockierende Webserver, der FriendFeed unterstützt. Es bietet einige WSGI-Server-Funktionalität, die wie unten beschrieben verwendet werden können. In der vorherigen Benchmark habe ich gezeigt, dass es eine ausgezeichnete Rohe-Steckdose bietet. Nachdem er mit PIP-Twisted-Installation erhalten Sie ein Werkzeug 8216twistd8217, die Sie WSGI Anwendungen fe leicht bedienen können: wistd 8211pidfiletmptwisted. pid - kein Web 8211wsgipong. application 8211logfiledevnull Sie können aber auch eine WSGI-Anwendung ausführen, wie folgt: uwsgi ein Server in C geschrieben ist, Es ist nicht dazu gedacht, eigenständig zu laufen, sondern muss hinter einen Webserver gestellt werden. Es bietet Module für Apache, NGINX, Cherokee und Lighttpd. Ich habe es hinter NGINX gelegt, die ich wie folgt konfiguriert: Das machte NGINX auf einem Unix-Socket hören, jetzt alles, was ich tun musste, war haben uwsgi zu gleichen Unix-Socket verbinden, die ich mit dem folgenden Befehl tat: uwsgi - s varnginxuwsgi. Sock - i - H homenicholasbenchmarkwsgibench - M - p 1 - w pong - z 30 - l 500 - L WsgiRef ist der Standard-WSGI-Server, der seit Version 2.5 mit Python ausgestattet ist. Um diesen Server ausführen meine Anwendung Ich verwende den folgenden Code, der die Protokollierung deaktiviert und erhöht den Rückstand. Im Folgenden finden Sie die Ergebnisse, wie mit Highcharts gezeichnet, die Linie wird verdicken, wenn über hovered und Sie können leicht aktivieren oder deaktivieren geplottet Ergebnisse, indem Sie auf die Legende. HTTP 1.0 Server-Ergebnisse Aus dem obigen Diagramm sollte klar sein, dass einige der Web-Server fehlen, der Grund ist, dass ich nicht in der Lage, sie vollständig benchmarked haben, da sie aufhörten zu antworten, wenn die Anfrage-Rate einen bestimmten kritischen Wert bestanden. Die Server, die fehlen, sind: MagnumPy, ich war in der Lage, eine Antwortrate von 500 RPS zu erhalten, aber wenn die Anfragerate die 700 RPS-Marke überschritten, stürzte MagnumPy Concurrence, war ich in der Lage, eine erfolgreiche Antwortrate von 700 RPS zu erhalten, aber Es hörte zu antworten, wenn wir mehr als 800 Anfragen eine Sekunde auf dem Server gefeuert. Allerdings, da Concurrence unterstützt HTTP1.1 halten lebendige Verbindungen und verhält sich richtig, wenn Benchmarked unter einer niedrigeren Verbindungsgeschwindigkeit, aber höhere Anfrage-Rate finden Sie ihre Ergebnisse in der HTTP1.1-Benchmark Cogen, konnte eine Antwortrate von 800 pro Sekunde zu erhalten Aber hörte auf zu antworten, wenn die Anfragerate über 1500 pro Sekunde lag. Es hat einen kompletten Benchmark unter dem HTTP1.1 Test aber. WSGIRef, erhielt ich eine Antwortquote von 352, aber es hörte auf zu reagieren, wenn wir die 1900 RPS-Marke Paster bestanden, erhielt eine Antwortzahl von 500, aber es scheiterte, wenn wir die 2000 RPS-Marke überschritten Von den Servern, die die Benchmark bestanden, können wir sehen, dass sie Alle haben eine bewundernswerte Leistung. An der Unterseite haben wir Twisted und Gunicorn, die Leistung von Twisted ist etwas auch erwartet es isn8217t wirklich für WSGI Leistung abgestimmt. Ich finde, die Leistung von Gunicorn etwas enttäuschend, auch weil zum Beispiel Aspen, die eine reine Python aus ein paar Jahren zurück ist, zeigt eine signifikante bessere Leistung. Wir können jedoch sehen, dass die Erhöhung der Zahl der Arbeitnehmer tatsächlich verbessert die Leistung, da es in der Lage, eine Antwort-Rate mit Aspen konkurrenzfähig ist. Die anderen reinen Python-Servern, CherryPy und Tornado scheinen auf Parität mit ModWSGI. Es sieht so aus, dass CherryPy einen leichten Leistungsvorteil gegenüber Tornado hat. So, wenn Sie denken, von ModWSGI oder CherryPy zu Tornado wegen der erhöhten Leistung zu ändern, sollten Sie wieder denken. Nicht nur dieser Benchmark zeigt, dass es so viel zu gewinnen gibt. Aber Sie werden auch das processthread-Modell verlassen, was bedeutet, dass Sie vorsichtig sein sollten, wenn Code Ihren Dolmetscher blockiert. Die Top-Performer sind eindeutig FAPWS3, UWSGI und Gevent. FAPWS3 wurde entwickelt, um schnell zu sein und lebt die Erwartungen, dies wurde von anderen als auch bemerkt, wie es aussieht, wie es in der Produktion bei Ebay verwendet wird. UWSGI wird erfolgreich in der Produktion bei (und in Entwicklung von) dem italienischen ISP Unbit verwendet. Gevent ist ein relativ junges Projekt, aber schon sehr erfolgreich. Nicht nur, dass es große Leistung in der vorherigen asynchronen Server-Benchmark, sondern seine Abhängigkeit von der Libevent HTTP-Server gibt es eine Leistung jenseits der anderen asynchronen Frameworks. Ich sollte beachten, dass der Unterschied zwischen diesen Top 3 ist zu klein, um einen klaren Sieger der 8216reply Rate contest8217 erklären. Allerdings möchte ich betonen, dass mit fast allen Servern musste ich vorsichtig sein, um die Menge der gleichzeitigen Verbindungen niedrig, da Gewinde-Server aren8217t, dass viele Lose gleichzeitige Verbindungen zu halten. Die asynchronen Server (Gevent, Eventlet und Tornado) waren glücklich, an dem zu arbeiten, was auf sie geworfen wurde. Dies gibt wirklich ein großes Gefühl der Stabilität, da Sie nicht über Einstellungen wie Poolsize, Arbeitnehmer zählen etc .. Sorgen machen müssen. Die meisten der Server haben eine akzeptable Reaktionszeit. Twisted und Eventlet sind etwas auf der langsamen Seite, aber Gunicorn zeigt leider einen dramatischen Anstieg der Latenz, wenn die Anforderungsrate die 1000 RPS-Marke überschreitet. Das Erhöhen der Gunicorn-Arbeiteranzahl verringert diese Latenz durch eine Menge, aber sie ist immer noch auf der hohen Seite verglichen mit beispielsweise Aspen oder CherryPy. Die niedrigen Fehlerraten für CherryPy, ModWSGI, Tornado, uWSGI sollten jedem das Vertrauen in ihre Eignung für eine Produktionsumgebung geben. HTTP 1.1 Server-Ergebnisse Im HTTP1.1-Benchmark haben wir eine unterschiedliche Teilnehmerliste, da nicht alle Server mehrere Anfragen über eine einzige Verbindung pipettieren konnten. In diesem Test ist die Verbindungsrate relativ gering, beispielsweise beträgt eine Anfragerate von 8000 pro Sekunde etwa 800 Verbindungen pro Sekunde bei 10 Anfragen pro Verbindung. Dies bedeutet, dass einige Server, die den HTTP1.0-Benchmark nicht abschließen konnten (mit Verbindungsraten bis zu 5000 pro Sekunde), in der Lage sind, den HTTP1.1-Benchmark (zB Cogen und Concurrence) abzuschließen. Diese Grafik zeigt die erreichte Anfragerate der Server und wir können deutlich sehen, dass die erreichte Anfragerate höher ist als im HTTP1.0-Test. Wir könnten die Gesamtanforderungsrate sogar noch erhöhen, indem wir die Anzahl der Pipeline-Anfragen erhöhen, aber dies würde dann die Verbindungsrate senken. Ich denke, dass 10 Pipeline Anfragen ist eine ok Verallgemeinerung eines Webbrowser Eröffnung einer durchschnittlichen Seite. Das Diagramm zeigt eine riesige Lücke in der Leistungsdifferenz, mit dem schnellsten Server Gevent können wir etwa 9000 Antworten pro Sekunde erhalten, mit Twisted, Concurrence und Cogen erhalten wir etwa 1000. In der Mitte haben wir CherryPy und ModWSGI mit ihnen sind wir in der Lage Um eine Antwort-Rate rund um die 4000 zu erhalten. Es ist interessant, dass Tornado während der Nähe von CherryPy und ModWSGI scheint eine Kante in diesem Benchmark im Vergleich zu der Kante CherryPy hatte in der HTTP1.0-Benchmark haben. Dies steht im Einklang mit unseren Erwartungen als Pipeline-Anfragen in Tornado sind billiger (da es Async ist), dann in ModWSGI oder CherryPy. Wir erwarten, dass sich diese Lücke erweitern wird, wenn wir die Anzahl der Pipeline-Anfragen erhöhen. Allerdings ist es zu sehen, wie viel von einem Performance-Boost dies würde in einem Deployment-Setup wie Tornado und CherryPy werden dann wahrscheinlich hinter einem Reverse-Proxy sitzen, zum Beispiel NGINX. In einer solchen Einstellung ist der Verbindungstyp zwischen dem Upstream und dem Proxy normalerweise auf HTTP1.0 beschränkt, NGINX beispielsweise unterstützt nicht einmal HTTP1.1, um lebendige Verbindungen zu seinen Upstreams zu halten. Die besten Darsteller sind eindeutig uWSGI und Gevent. Ich benchmarked Gevent mit der Option 8217spawnnone8217, um zu verhindern, dass Gevent ein Greenlet laicht, scheint dies fair in einer Benchmark wie diese. Allerdings, wenn Sie etwas Interessantes mit vielen gleichzeitigen Verbindungen wollen Sie jede Anfrage, um ihre eigenen Greentlet haben, da dies ermöglicht es Ihnen, Thread wie flow control haben. So habe ich auch benchmarked diese Version, die in der Grafik unter dem Namen 8216Gevent-Spawn8217 gesehen werden kann, aus seinen Ergebnissen können wir sehen, dass Performance-Strafe klein ist. Cogen erhält eine hohe Latenz nach etwa 2000 Anfragen pro Sekunde, Eventlet und Twisted zeigen eine erhöhte Latenzzeit ziemlich früh auch. Die Fehlerrate zeigt, dass Twisted, Concurrence und Cogen haben einige Mühe halten, ich glaube, alle anderen Fehlerraten sind akzeptabel. Speicherverbrauch Ich auch überwacht die Speicherauslastung der verschiedenen Frameworks während der Benchmark. Die unten genannte Benchmark ist die maximale Speicherauslastung aller akkumulierten Prozesse. Da diese Benchmark nicht wirklich von zusätzlichen Prozessen profitiert (da nur ein einziger Prozessor vorhanden ist) habe ich die Anzahl der Beschäftigten nach Möglichkeit begrenzt. Aus diesen Ergebnissen gibt es eine Sache, die wirklich abhebt und das ist die absolut geringe Speicherauslastung von uWSGI, Gevent und FAPWS3. Vor allem, wenn wir ihre Leistung berücksichtigen. Es sieht aus wie Cogen ist undicht Speicher, aber ich haven8217t wirklich in das sah. Gunicorn-3w zeigt im Vergleich zu Gunicorn einen relativ hohen Speicherverbrauch. Aber es ist zu beachten, dass dies vor allem durch den Wechsel von der nackten Bereitstellung zur Bereitstellung nach NGINX verursacht wird, da wir jetzt auch die Speicherauslastung von NGINX hinzufügen müssen. Ein einzelner Gunicorn-Arbeiter benötigt nur ca. 7,5 MB Speicher. Let8217s Kick it up eine Kerbe Der erste Teil dieser Post fokussiert rein auf die RPS-Performance der verschiedenen Frameworks unter einer hohen Belastung. Wenn der WSGI-Server hart genug arbeitete, konnte er einfach alle Anfragen eines bestimmten Benutzers beantworten und zum nächsten Benutzer wechseln. Dies hält die Menge der gleichzeitigen Verbindungen relativ niedrig, so dass eine solche Benchmark für Gewinde-Webserver geeignet. Wenn wir jedoch die Anzahl der gleichzeitigen Verbindungen erhöhen, werden wir schnell in die Systemgrenzen hineinlaufen, wie in der Einleitung erläutert. Dies ist allgemein bekannt als das C10K-Problem. Asynchrone Server verwenden einen einzigen Thread, um mehrere Verbindungen zu behandeln und bei effizienter Implementierung mit beispielsweise EPoll oder KQueue sind vollkommen in der Lage, eine große Anzahl von gleichzeitigen Verbindungen zu handhaben. Das ist, was wir tun werden, werden wir die Top-3 durchführen WSGI-Servern nehmen, nämlich Tornado, Gevent und uWSGI (FAPWS3 Mangel an HTTP1.1 Unterstützung machte es ungeeignet für diese Benchmark) und geben ihnen 5 Minuten Ping - pong Chaos. Sie sehen, Ping-Pong ist ein einfaches Spiel und es ist wirklich die Komplexität, die es interessant macht, ist es die Geschwindigkeit und die Reaktion der Spieler. Nun, was ist 5 Minuten Pingpong Chaos Stellen Sie sich vor, dass für 5 Minuten lang jede Sekunde ein Airbus mit Ping-Pong-Spieler landet (500 Klienten) und jeder dieser Spieler wird Sie zerschlagen Sie genau 12 Kugeln (mit einem 5-Sekunden-Intervall) . Das bedeutet, dass nach 5 Sekunden die Volleys von 2000 verschiedenen Spielern sofort zurückgegeben werden müssen. Tsung Benchmark Setup Um diesen Benchmark durchzuführen, werde ich Tsung verwenden. Das ein in Erlang geschriebenes Multiprotokoll - verteiltes Lasttestgerät ist. Ich werde dann 3 verschiedene Maschinen simulieren die Ping-Pong rampage. Ich habe das folgende Tsung-Skript verwendet. Tsung-Benchmark-Ergebnisse Lassen Sie mich zuerst erklären, dass alle drei Frameworks sind perfekt in der Lage, diese Art von Last zu behandeln, keines der Frameworks sank Verbindung oder ignoriert Anfragen. Was ich sagen muss, ist schon eine gute Leistung, wenn man bedenkt, dass sie etwa 2 Millionen Anfragen pro Tag abwickeln mussten. Unterhalb des gleichzeitigen Verbindungsgraphen sehen wir die Systembelastung, die CPU-Nutzung und den freien Speicher auf dem System während des Benchmarks. Wir können deutlich sehen, dass Gevent weniger Belastung für das System, wie die CPU-und Last-Diagramm anzeigen. In der Speicher-Grafik können wir sehen, dass alle Frameworks eine konsistente Menge an Speicher verwendet. Die Leser, die immer noch aufmerksam zu diesem Artikel beachten, beachten Sie, dass die Speicher-Grafik zeigt 4 Zeilen statt 3. Die vierte Zeile ist Gevent kompiliert gegen Libevent 2.0.4a. Die neue Version von Libevent hat gesagt, erhebliche Leistungsverbesserungen in seinem HTTP-Server zeigen. Aber es ist immer noch eine Alpha-Version und das Speicher-Diagramm zeigt, dass diese Version undicht Speicher ist. Nicht etwas, was Sie auf Ihrer Produktionsstätte wollen. Die endgültige Grafik zeigt die Latenz der 3 Frameworks, die wir sehen können einen deutlichen Unterschied zwischen Tornado und seine Konkurrenten als Tornado8217s Reaktionszeit schwebt rund 100ms, uWSGI rund 5ms und gevent um 3ms. Dies ist ein ganz anderer Unterschied und ich bin wirklich erstaunt über die geringe Latenz von Gevent und uWSGI während dieses Angriffs. Zusammenfassung und Anmerkungen Die obigen Ergebnisse zeigen, dass wir als Python-Webentwickler viele verschiedene Methoden zur Implementierung unserer Anwendungen haben. Einige von diesen scheinen besser zu funktionieren als andere, aber durch die Fokussierung nur auf Server-Leistung Ich werde nicht rechtfertigen die meisten der getesteten Servern, da sie stark in Funktionalität unterscheiden. Auch, wenn Sie gehen zu nehmen einige Stock Web-Framework und won8217t keine Optimierungen oder Caching, die Leistung Ihres Webservers wird nicht zu einer Angelegenheit, da dies nicht der Engpass werden. Wenn es eine Sache, die diese Benchmark deutlich gemacht ist, dass die meisten Python-Web-Server bieten große Leistung und wenn Sie das Gefühl, die Dinge sind langsam das erste, was zu sehen ist wirklich Ihre eigene Anwendung. Wenn Sie nur daran interessiert, schnell Hosting Ihre Gewindeanwendung Sie wirklich can8217t gehen falsch mit Apache ModWSGI. Obwohl Apache ModWSGI ein wenig mehr Belastung für Ihre Speicheranforderungen stellen könnte, gibt es für die Funktionalität viel zu tun. Beispielsweise ist das Schützen eines Teils Ihrer Website durch Verwendung eines LDAP-Servers so einfach wie das Aktivieren eines Moduls. Standalone CherryPy zeigt auch große Leistung und Funktionalität und ist wirklich eine lebensfähige (vollständig Python) Alternative, die Speicheranforderungen senken kann. Wenn Sie ein wenig mehr abenteuerlich können Sie bei uWSGI und FAPWS3, sie sind relativ neu im Vergleich zu CherryPy und ModWSGI, aber sie zeigen eine signifikante Leistungssteigerung und haben weniger Speicher Anforderungen. In Bezug auf Tornado und Leistung, ich glaube nicht, dass Tornado ist eine Alternative für CherryPy oder sogar ModWSGI. Nicht nur, dass es kaum zeigen keine Leistungssteigerungen, aber es erfordert auch, dass Sie Ihren Code zu überdenken. Aber Tornado kann eine gute Option, wenn Sie keinen Code mit blockierenden Verbindungen oder wollen einfach nur, um etwas Neues zu sehen. Und dann gibt es Gevent. Es wirklich zeigte erstaunliche Leistung bei einem geringen Speicherbedarf, könnte es einige Anpassungen an Ihren Legacy-Code benötigen, aber dann wieder die Affen-Patching der Sockel-Modul könnte helfen, und ich liebe die Sauberkeit der Greenlets. Es gab bereits einige Berichte über die erfolgreiche Implementierung von Gevent auch mit SQLAlchemy. Und wenn Sie in Hochleistungs-Webseiten mit vielen gleichzeitigen Verbindungen tauchen möchten, müssen Sie wirklich mit einem asynchronen Framework zu gehen. Gevent scheint wie der perfekte Begleiter dafür, zumindest das ist, was wir verwenden werden. 114 Responses to 8220Benchmark von Python WSGI Servers8221 I8217m neugierig, wenn Sie überprüft, dass die Threadpools in jedem Server waren die gleiche Größe (für diejenigen Server mit Threadpools. Dies könnte einen signifikanten Unterschied in den Ergebnissen. Es könnte auch interessant sein, darüber zu lernen Was die Erhöhung der Threadpool-Größe nicht mehr hilft Leistung. It8217s auch erwähnenswert, dass einige der Top-Performer, nicht mit Threads, sind nicht tatsächlich die Umsetzung eines allgemeinen Zweck, skalierbare WSGI-Server. Sie nehmen eine wertvolle Verknüpfung, die Leistung unterstützt, aber dies Sollte bei der Auswahl eines Servers berücksichtigt werden, da es zu katastrophaler Performance für bestimmte Anwendungen führen könnte. I8217m auch neugierig, wenn Sie eine Analyse der Fehler einige der Server angetroffen. Unter den Untersuchungen, I8217ve häufig festgestellt, dass dies eng an Anfrage gebunden ist Wenn ein Server anfängt, hinter der Anforderungsrate zu liegen, falls er nicht weiterhin neue Verbindungen akzeptiert, beginnen viele TCPIP-Stapel, eingehende TCP-Verbindungen selbst abzulehnen. Dies ist ein wenig nützlich zu wissen, aber ich denke, es lohnt sich von einem Fehler, der tatsächlich innerhalb der Software getestet wird, zu trennen, zumal in diesem Fall es meistens redundant mit den Informationen über die Anzahl der Anfragen Sekunden pro Server reagieren kann. Eine letzte Sache. Ich frage mich, wenn Sie irgendwelche Informationen über die Verteilung der Antwortzeiten haben. Die Graphen der mittleren (I annehmen) Zeiten sind interessant, aber zu wissen, was die Rohdaten aussehen, ist auch wichtig (und eigentlich notwendig, um korrekt interpretieren Sie den Rest der Daten, die Sie hier vorgestellt). Große Arbeit so weit. Ich hoffe, Sie halten es. Ich hoffe auch, dass irgendwann dort etwas heruntergeladen werden kann, dass die Leute verwenden können, um Ihre Ergebnisse zu reproduzieren, sowie die Analyse auf sie getan zu verlängern. Ich habe versucht, die Leistung der verschiedenen Frameworks durch die Optimierung der Threadpool zu maximieren, aber das ist ein bisschen schmerzhaft durchzuführen, denn wenn ein Pool zu groß wird, kann er den Server abstürzen. So nehme ich an, dass einige Gewinne möglich sind, aber ich vermute, dass diese Gewinne relativ klein sein werden. In Bezug auf die Fehler, können Sie einen Unterschied in der Art von Fehlern zwischen den Servern, die in der Lage, die Benchmark und diejenigen, die aren8217t abgeschlossen sind zu sehen. Aber ja ich könnte angegeben haben, ob es war ein Verbindungs-Reset oder ein Timeout, aber der Artikel wurde wirklich lange schon. Die Mittelwerte sind in der Tat in der Grafik dargestellt, während ich einverstanden, dass die STD wäre interessant zu zeigen, wie gut die Graphen sind bereits sehr voll und ich finde, dass die Kurve kann mir einige Hinweise auf die Stabilität des Mittelwerts. Zum Beispiel vergleichen uWSGI gegen FAPWS3 nach der 6000 RPS Marke miteinander. Ich überprüft, und zunehmende Thread-Pool-Größe hat erheblichen Einfluss auf Twisted (YMMV), so dass ich vermute, dass das gleiche wäre für andere Thread-Pool-basierte Frameworks. Sehr interessanter Benchmark bestätigt es meine persönlichen Erfahrungen mit dem WSGI Webserver Ich habe modwsgi cherrypy und uwsgi getestet. Ich wäre interessant zu wissen, welche Version für jeden Webserver Sie verwendet haben. Nur eine Notiz über die Gunicorn-Nummern. Das Ausführen des Servers mit einem einzelnen Arbeitsprozess beschränkt alle Möglichkeiten für Parallelität in seinen Antworten. Es soll mit 2-4x die Anzahl der Prozessoren laufen, die Sie auf der Maschine haben. There8217s auch eine kleine gotchya in der Motivation für die Implementierung von HTTP1.1. Nginx8217s Proxy ist nur HTTP1.0, so dass, wenn Sie es verwenden müssen, um Skalierung mehrere Python-Server-Prozesse there8217s keinen Nutzen aus HTTP1.1 weshalb gunicorn didn8217t Mühe, es zu implementieren. (Wie es von nginx projiziert werden soll). Wenn ich etwas Zeit später I8217ll und versuchen, einige dieser Zahlen auf größere Hardware. I8217ve persönlich gesehen gunicorn laufen, dass HTTP1.0 Benchmark 10K reqs schneller als gevent tut. Thanks for the writeup, Paul Davis I understand these gotcha and i mentioned it in the article. If i could be of any help please let me know. I could rerun the bench somewhere in the future with more assigned processors and workers to specifically test out that case, if you want. Remember that gunicorn isn8217t like the rest of web servers in terms of its process utilization. Even when its only got a single core allocated for use it will still benefit from an increase in the number of workers allocated. Configuring gunicorn with a single worker is like configuring all the threaded servers to use a single thread, its just not how it was intended to be run. Also, in your httperf invocation, did you keep the number of connections a constant for every test Ie, were the 4K rs tests taking 110th of a second That might explain some of the noise in the graphs. I am running Gunicorn right now with 3 workers, thus i have a master processes and 3 workers (and ofcourse the NGINX processes). I8217ll add it to the benchmark when its done, the main reason why i did not try multiple workers was because this would have a negative influence on the memory statistics and I did not expect any performance increase. From the initial results i8217m getting back from the current benchmark it does seem to improve the results for Gunicorn moving it to a more respectable position. Feel free to report the sum of the process memory. There are some oddities with copy-on-write semantics but I8217ve never heard of a good way to tease those apart for proper usage reports. You mentioned putting uWSGI behind nginx but didn8217t say anything about doing the same for gunicorn. Does that mean you ran the benchmarks without nginx proxying for gunicorn Gunicorn isn8217t designed to be used like that 8212 it8217s supposed to live behind nginx (or something similar) just like uWSGI. gunicorn. orgdeployment. html describes the way you8217re supposed to deploy gunicorn. Thats correct, however, i did try to put it behind NGINX (via a Unix socket) and that did not give me any performance increase. I am also having a difficult time how that would improve performance as I only use a single worker. In this specific case it doesn8217t matter whether you run gunicorn behind nginx as the wsgi app and the clients are both super duper fast. Gunicorn depends on having a buffering proxy to deal with client load as described at 1. Slowloris is obviously an extreme example of slow client behavior but a public facing server will obviously be exposed to the entire spectrum of client speed between super fast and super slow. Using 8216ThreadsPerChild 160008242 for Apachemodwsgi is just plain stupid. It is directly because of that that it had such a large memory footprint. If you drop that value down to below 100 you will probably find the same performance and yet a lot less memory being used. If your test program is merely a hello world application that returns a few bytes, you could possibly get away with a lot less threads than 100. Some high performance sites with a lot of requests, but where Apache and the application has been tuned properly, get away with 2 or 3 threads in single daemon mode process. When using Apachemodwsgi, forcing use of a single process is also going to make performance suffer due to limitations of the GIL. The strength of Apachemodwsgi is that you can fire up multiple processes and avoid these GIL issues, especially where using a multi processorcore system. I suggest you go back and redo your Apachemodwsgi tests starting with the Apache default of 25 threads in one process for embedded. If you see it start to suffer under high number of concurrent requests, then add more processes as well and not just threads, with more processes and dropping threads actually better. Thanks, for your remarks Graham. I obviously did not have the amount of threads set to that insane amount of 16k as this will invoke the OOM killer on my machine. The 16k setting is a left over from when i tried to have Apache competing in the Tsung benchmark, that didn8217t work. As noted i experimented with some of the settings to obtain an optimal balance of not increasing the error rate (in the HTTP 1.1 benchmark which can force a lot of concurrent connections). For the benchmark i used a thread setting of 1000, lowering this number would raise the error rate. With this setting the memory usage starts at a relatively low of 21Mb but as the benchmark progresses it reaches 64Mb. I could try splitting the amount of threads over multiple processes because indeed the issues you mention could indeed hold back ModWSGI its performance. But I suppose that this would increase the memory usage, at least this was the main reason why I decided to limit it to one process. I will see, when and if I re-benchmark it. Btw, your other comment just popped in. I did not find out how to disable logging on Apache, can you give me a pointer Really interesting benchmark, but i think it could be really interesting to turn it in a challenge and make it more 8216real world usage8217 by only providing apps: - a simple pingpong app - a simple django app - a django app template - django app sqlite reads and or memcache readwrite and ask each server8217s community to tune and provide the optium setup for its specific server to achieve best performance. Also using hardware that is more uptodate, because i don8217t know any serious job getting done on a single core anymore I think that quad core and 24Go or ram is a better view of the server market. this challenge could be run on EC2 instances for example. And it should be noted that even the worse server in your benchmark with (1000 rs on a single core) would provide enought performance for 99 of current website needs. So feature and ease of use should be taken into account to choose a wsgi server. Great article, can8217t wait to read the next one First of all: nice benchmarks I must admit however that for choosing a Python WSGI server, I8217d base my choice for at least 50 on benchmarks with basic POST data handling to see what it8217s capable of8230 Maybe a follow up Very very useful test. Thanks for sharing it. Tornado looks great if all your communications are short bursts, but I8217m looking at gevent because some of our responses can be quite large. As a result, we would be unable to use the 8220normal8221 gevent. wsgi server (which is really the libevent server if I understand correctly) because we can8217t afford to buffer the messages in RAM for all those connections. I was wondering whether you have timing for gevent using the pywsgi server, which supports SSL and chunked response. I imagine that it would have very different characteristics. Yes, I8217d be very interested in seeing how gevent8217s pywsgi server compares. I8217m surprised Nicholas didn8217t mention the lack of keep-alive support in the libevent-http based one. At the time I tested gevent, the libevent server still had keep-alives enabled by default. The change to disable it is more recent than this benchmark and you can still enable it if you want. But I agree, it will be very interesting to test the PyWSGI server
Comments
Post a Comment