{"id":35106,"date":"2019-10-31T22:02:22","date_gmt":"2019-10-31T19:02:22","guid":{"rendered":"https:\/\/prohoster.info\/blog\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie\/"},"modified":"2019-10-31T22:02:22","modified_gmt":"2019-10-31T19:02:22","slug":"proizvoditelnost-setevyh-prilozhenij-linux-vvedenie","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie","title":{"rendered":"Die Leistung von Netzwerk-Anwendungen unter Linux. Einleitung","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Webanwendungen werden heute \u00fcberall eingesetzt, und HTTP macht dabei den L\u00f6wenanteil unter allen Transportprotokollen aus. Bei der Untersuchung der Nuancen der Webanwendungsentwicklung schenken die meisten der zugrunde liegenden Betriebssystemumgebung, in der diese Anwendungen tats\u00e4chlich betrieben werden, nur wenig Aufmerksamkeit. Die Trennung zwischen Entwicklung (Dev) und Betrieb (Ops) hat die Situation nur versch\u00e4rft. Mit dem Aufstieg der DevOps-Kultur beginnen Entwickler jedoch, die Verantwortung f\u00fcr den Betrieb ihrer Anwendungen in der Cloud zu \u00fcbernehmen, weshalb es f\u00fcr sie sehr hilfreich ist, das Backend des Betriebssystems gr\u00fcndlich zu verstehen. Dies ist besonders vorteilhaft, wenn Sie versuchen, ein System f\u00fcr Tausende oder Zehntausende gleichzeitiger Verbindungen bereitzustellen.<\/p>\n<p>Einschr\u00e4nkungen in Webdiensten \u00e4hneln stark den Einschr\u00e4nkungen in anderen Anwendungen. Egal, ob es sich um Lastenausgleichsmechanismen oder Datenbankserver handelt, all diese Anwendungen haben \u00e4hnliche Probleme in einer leistungsstarken Umgebung. Das Verst\u00e4ndnis dieser grundlegenden Einschr\u00e4nkungen und Strategien zu deren \u00dcberwindung erm\u00f6glicht eine bessere Einsch\u00e4tzung der Leistung und Skalierbarkeit Ihrer Webanwendungen.<\/p>\n<p>Ich schreibe diese Artikelreihe als Antwort auf die Fragen junger Entwickler, die gut informierte Systemarchitekten werden m\u00f6chten. Es ist unm\u00f6glich, die Methoden zur Optimierung von Linux-Anwendungen klar zu verstehen, ohne sich mit den Grundlagen auseinander zu setzen, wie sie auf Betriebssystemebene funktionieren. Obwohl es viele Arten von Anwendungen gibt, m\u00f6chte ich in diesem Zyklus Netzwerkanwendungen und nicht Desktop-Anwendungen wie Browser oder Texteditoren untersuchen. Dieses Material richtet sich an Entwickler und Architekten, die verstehen m\u00f6chten, wie Programme unter Linux oder Unix funktionieren und wie man sie f\u00fcr hohe Leistung strukturiert.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nLinux ist <i>ein serverbetriebssystem<\/i> , und Ihre Anwendungen laufen h\u00e4ufig genau auf diesem Betriebssystem. Obwohl ich \"Linux\" sage, k\u00f6nnen Sie die meiste Zeit mit Sicherheit annehmen, dass alle Unix-\u00e4hnlichen Betriebssysteme im Allgemeinen gemeint sind. Dennoch habe ich den begleitenden Code nicht auf anderen Systemen getestet. Wenn ich also etwas Linux-spezifisches ausprobiere, weise ich darauf hin.<\/p>\n<p>Obwohl Sie das erworbene Wissen nutzen k\u00f6nnen, um eine Anwendung von Grund auf neu zu erstellen, die hervorragend optimiert ist, ist es besser, dies zu vermeiden. Wenn Sie einen neuen Webserver in C oder C++ f\u00fcr die Gesch\u00e4ftsanwendung Ihrer Organisation schreiben, k\u00f6nnte dies Ihr letzter Arbeitstag sein. Das Wissen \u00fcber die Struktur dieser Anwendungen hilft jedoch bei der Auswahl bereits existierender Programme. Sie k\u00f6nnen Systeme auf Basis von Prozessen mit Systemen auf Basis von Threads sowie auf Basis von Ereignissen vergleichen. Sie werden verstehen und sch\u00e4tzen, warum Nginx besser funktioniert als Apache httpd und warum eine Python-Anwendung auf Basis von Tornado mehr Benutzer bedienen kann als eine Python-Anwendung auf Basis von Django.<\/p>\n<h1>ZeroHTTPd: Lernwerkzeug<\/h1>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/shuveb\/zerohttpd\">ZeroHTTPd<\/a><\/noindex>\u00a0\u2014 ein Webserver, den ich von Grund auf in C als Lernwerkzeug geschrieben habe. Er hat keine externen Abh\u00e4ngigkeiten, einschlie\u00dflich des Zugriffs auf Redis. Wir f\u00fchren unsere eigenen Redis-Prozeduren aus. Weitere Informationen finden Sie weiter unten.<\/p>\n<p>Obwohl wir die Theorie lange diskutieren k\u00f6nnten, gibt es nichts Besseres, als Code zu schreiben, ihn auszuf\u00fchren und alle Serverarchitekturen miteinander zu vergleichen. Dies ist die anschaulichste Methode. Deshalb werden wir einen einfachen Webserver ZeroHTTPd schreiben und jedes Modell anwenden: auf Basis von Prozessen, Threads und Ereignissen. Wir werden jeden dieser Server testen und sehen, wie sie im Vergleich zueinander funktionieren. ZeroHTTPd wird in einer einzigen C-Datei implementiert. Der Ereignis-basierte Server enth\u00e4lt <noindex><a rel=\"nofollow\" href=\"https:\/\/troydhanson.github.io\/uthash\/\">uthash<\/a><\/noindex>, eine hervorragende Implementierung einer Hash-Tabelle, die in einer einzigen Header-Datei geliefert wird. In den anderen F\u00e4llen gibt es keine Abh\u00e4ngigkeiten, um das Projekt nicht zu komplizieren.<\/p>\n<p>Der Code enth\u00e4lt viele Kommentare, um beim Verst\u00e4ndnis zu helfen. Als einfacher Webserver in wenigen Codezeilen stellt ZeroHTTPd auch ein minimales Framework f\u00fcr die Webentwicklung dar. Es hat eine begrenzte Funktionalit\u00e4t, kann jedoch statische Dateien ausliefern und sehr einfache \u201edynamische\u201c Seiten erstellen. Ich muss sagen, dass ZeroHTTPd gut geeignet ist, um zu lernen, wie man leistungsstarke Linux-Anwendungen erstellt. Im Grunde genommen warten die meisten Webdienste auf Anfragen, \u00fcberpr\u00fcfen sie und verarbeiten sie. Genau das wird ZeroHTTPd tun. Es ist ein Lernwerkzeug und nicht f\u00fcr den produktiven Einsatz gedacht. Es hat keine starken F\u00e4higkeiten zur Fehlerbehandlung und wird wahrscheinlich nicht mit den besten Sicherheitspraktiken prahlen (oh ja, ich habe verwendet <code>strcpy<\/code>) oder mit abstrusen Tricks der Sprache C. Aber ich hoffe, dass er seine Aufgabe gut meistern wird.<\/p>\n<p><img decoding=\"async\" alt=\"Die Leistung von Netzwerk-Anwendungen unter Linux. Einleitung\" src=\"\/wp-content\/uploads\/33fd0a5353667001523d5d4c8ada9ecf.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Startseite von ZeroHTTPd. Er kann verschiedene Dateitypen ausgeben, einschlie\u00dflich Bilder<\/i><\/p>\n<h1>Anwendung f\u00fcr ein G\u00e4stebuch<\/h1>\n<p>\nModerne Webanwendungen sind in der Regel nicht auf statische Dateien beschr\u00e4nkt. Sie haben komplexe Interaktionen mit verschiedenen Datenbanken, Caches usw. Daher werden wir eine einfache Webanwendung namens \u201eG\u00e4stebuch\u201c erstellen, in der Besucher Eintr\u00e4ge unter ihren Namen hinterlassen. Das G\u00e4stebuch speichert zuvor hinterlassene Eintr\u00e4ge. Au\u00dferdem gibt es einen Z\u00e4hler f\u00fcr die Besucher am unteren Rand der Seite.<\/p>\n<p><img decoding=\"async\" alt=\"Die Leistung von Netzwerk-Anwendungen unter Linux. Einleitung\" src=\"\/wp-content\/uploads\/ed8e828e8567d3d114875520988742d7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Webanwendung \u201eG\u00e4stebuch\u201c ZeroHTTPd<\/i><\/p>\n<p>Der Besucherz\u00e4hler und die Eintr\u00e4ge des G\u00e4stebuchs werden in Redis gespeichert. F\u00fcr die Kommunikation mit Redis wurden eigene Prozeduren implementiert, die nicht von externen Bibliotheken abh\u00e4ngen. Ich bin kein gro\u00dfer Fan davon, eigenen Code zu entwickeln, wenn es \u00f6ffentliche und gut getestete L\u00f6sungen gibt. Aber das Ziel von ZeroHTTPd ist es, die Leistung von Linux und den Zugriff auf externe Dienste zu studieren, w\u00e4hrend die Bearbeitung von HTTP-Anfragen die Leistung erheblich beeinflusst. Wir m\u00fcssen die Kommunikation mit Redis in jeder unserer Serverarchitekturen vollst\u00e4ndig kontrollieren. In einer Architektur verwenden wir blockierende Aufrufe, in anderen prozedurbasierte Ereignisse. Die Verwendung einer externen Client-Bibliothek f\u00fcr Redis w\u00fcrde diese Kontrolle nicht erm\u00f6glichen. Zudem f\u00fchrt unser kleiner Redis-Client nur einige Funktionen aus (Abruf, Einstellung und Erh\u00f6hung eines Schl\u00fcssels; Abruf und Hinzuf\u00fcgen zu einem Array). Dar\u00fcber hinaus ist das Redis-Protokoll \u00e4u\u00dferst elegant und einfach. Man muss es nicht einmal speziell lernen. Die Tatsache, dass die gesamte Arbeit des Protokolls in etwa einhundert Zeilen Code erledigt wird, zeigt, wie gut es durchdacht ist.<\/p>\n<p>Im folgenden Bild sind die Vorg\u00e4nge der Anwendung dargestellt, wenn der Client (Browser) anfragt <code>\/guestbookURL<\/code>.<\/p>\n<p><img decoding=\"async\" alt=\"Die Leistung von Netzwerk-Anwendungen unter Linux. Einleitung\" src=\"\/wp-content\/uploads\/5c5e6740419384b7232aeead95db491b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Funktionsweise der G\u00e4stebuchanwendung<\/i><\/p>\n<p>Wenn eine Seite des G\u00e4stebuchs ausgegeben werden soll, erfolgt ein Aufruf des Dateisystems zum Lesen der Vorlage in den Speicher und drei Netzwerkaufrufe an Redis. Die Vorlagendatei enth\u00e4lt den Gro\u00dfteil des HTML-Inhalts f\u00fcr die Seite auf dem obigen Screenshot. Dort gibt es auch spezielle Platzhalter f\u00fcr die dynamischen Inhalte: die Eintr\u00e4ge und den Besucherz\u00e4hler. Wir erhalten diese aus Redis, f\u00fcgen sie in die Seite ein und liefern den vollst\u00e4ndig formatierten Inhalt an den Client aus. Den dritten Redis-Abruf kann man vermeiden, da Redis den neuen Wert des Schl\u00fcssels beim Erh\u00f6hen zur\u00fcckgibt. F\u00fcr unseren Server mit einer ereignisgesteuerten asynchronen Architektur ist jedoch eine Vielzahl von Netzwerkaufrufen eine gute \u00dcbung zu Lernzwecken. Daher ignorieren wir den von Redis zur\u00fcckgegebenen Wert der Besucheranzahl und fordern ihn in einem separaten Aufruf an.<\/p>\n<h1>Serverarchitekturen von ZeroHTTPd<\/h1>\n<p>\nWir erstellen sieben Versionen von ZeroHTTPd mit derselben Funktionalit\u00e4t, jedoch mit unterschiedlichen Architekturen:<\/p>\n<ul>\n<li>Iterativ\n<\/li>\n<li>Fork-Server (ein Kindprozess pro Anfrage)\n<\/li>\n<li>Pre-Fork-Server (vorheriges Forking von Prozessen)\n<\/li>\n<li>Server mit Ausf\u00fchrungsthreads (ein Thread pro Anfrage)\n<\/li>\n<li>Server mit vorab erstellten Threads\n<\/li>\n<li>Architektur auf Basis von <code>poll()<\/code>\n<\/li>\n<li>Architektur auf Basis von <code>epoll<\/code><\/li>\n<\/ul>\n<p>\nWir messen die Leistung jeder Architektur, indem wir den Server mit HTTP-Anfragen belasten. Bei Vergleichen von Architekturen mit einem hohen Grad an Parallelit\u00e4t steigt die Anzahl der Anfragen. Wir testen dreimal und berechnen den Durchschnitt.<\/p>\n<h1>Testmethodologie<\/h1>\n<p>\n<img decoding=\"async\" alt=\"Die Leistung von Netzwerk-Anwendungen unter Linux. Einleitung\" src=\"\/wp-content\/uploads\/aa4f337b6e90fa032fbef5374fac8f53.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Setup f\u00fcr Lasttests von ZeroHTTPd<\/i> <\/p>\n<p>Es ist wichtig, dass w\u00e4hrend der Tests nicht alle Komponenten auf einer Maschine laufen. In diesem Fall bringt das Betriebssystem zus\u00e4tzliche Overheadkosten f\u00fcr die Planung mit sich, da die Komponenten um die CPU konkurrieren. Die Messung der \u00dcberheadkosten des Betriebssystems f\u00fcr jede der gew\u00e4hlten Serverarchitekturen ist eines der wichtigsten Ziele dieser \u00dcbung. Das Hinzuf\u00fcgen weiterer Variablen wird den Prozess beeintr\u00e4chtigen. Daher funktioniert die obige Konfiguration am besten.<\/p>\n<h3>Was jeder dieser Server macht<\/h3>\n<p><\/p>\n<ul>\n<li>load.unixism.net: hier f\u00fchren wir aus <code>ab<\/code>, das Apache Benchmark-Tool. Es erzeugt die Last, die erforderlich ist, um unsere Serverarchitekturen zu testen.\n<\/li>\n<li>nginx.unixism.net: Manchmal m\u00f6chten wir mehr als eine Instanz eines Serverprogramms ausf\u00fchren. Daf\u00fcr arbeitet der Nginx-Server mit den entsprechenden Einstellungen als Lastverteiler f\u00fcr <i>ab<\/i> unsere Serverprozesse.\n<\/li>\n<li>zerohttpd.unixism.net: Hier f\u00fchren wir unsere Serverprogramme auf sieben verschiedenen Architekturen aus, jeweils einzeln.\n<\/li>\n<li>redis.unixism.net: Auf diesem Server l\u00e4uft der Redis-Daemon, wo die Eintr\u00e4ge im G\u00e4stebuch und der Z\u00e4hler der Besucher gespeichert werden.<\/li>\n<\/ul>\n<p>\nAlle Server laufen auf einem einzelnen Prozessor-Kern. Die Idee ist, die maximale Leistung jeder Architektur zu bewerten. Da alle Serverprogramme auf derselben Hardware getestet werden, ist dies die Basislinie f\u00fcr ihren Vergleich. Meine Testumgebung besteht aus virtuellen Servern, die bei Digital Ocean gemietet werden.<\/p>\n<h3>Was messen wir?<\/h3>\n<p>\nEs k\u00f6nnen verschiedene Kennzahlen gemessen werden. Wir bewerten die Leistung jeder Architektur in dieser Konfiguration, indem wir die Server mit Anfragen auf unterschiedlichen Parallelisierungsstufen belasten: die Last steigt von 20 bis 15.000 gleichzeitigen Benutzern.<\/p>\n<h1>Testergebnisse<\/h1>\n<p>\nIm n\u00e4chsten Diagramm wird die Leistung der Server auf verschiedenen Architekturen bei unterschiedlichen Parallelisierungsstufen gezeigt. Auf der y-Achse steht die Anzahl der Anfragen pro Sekunde, auf der x-Achse die parallelen Verbindungen.<\/p>\n<p><img decoding=\"async\" alt=\"Die Leistung von Netzwerk-Anwendungen unter Linux. Einleitung\" src=\"\/wp-content\/uploads\/3415bcfb66503152d644130f68bd19da.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Die Leistung von Netzwerk-Anwendungen unter Linux. Einleitung\" src=\"\/wp-content\/uploads\/ba457b671eb758f3226e0eeafaadc6aa.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Die Leistung von Netzwerk-Anwendungen unter Linux. Einleitung\" src=\"\/wp-content\/uploads\/aea06856d61d4d4bdda9814c53a28d4a.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnten ist eine Tabelle mit den Ergebnissen.<\/p>\n<p> Anfragen pro Sekunde <\/p>\n<p><strong>Parallelismus<\/strong><br \/>\n<strong>iterativ<\/strong><br \/>\n<strong>Fork<\/strong><br \/>\n<strong>pre-fork<\/strong><br \/>\n<strong>threaded<\/strong><br \/>\n<strong>pre-threaded<\/strong><br \/>\n<strong>poll<\/strong><br \/>\n<strong>epoll<\/strong><\/p>\n<p>20<br \/>\n7<br \/>\n112<br \/>\n2100<br \/>\n1800<br \/>\n2250<br \/>\n1900<br \/>\n2050<\/p>\n<p>50<br \/>\n7<br \/>\n190<br \/>\n2200<br \/>\n1700<br \/>\n2200<br \/>\n2000<br \/>\n2000<\/p>\n<p>100<br \/>\n7<br \/>\n245<br \/>\n2200<br \/>\n1700<br \/>\n2200<br \/>\n2150<br \/>\n2100<\/p>\n<p>200<br \/>\n7<br \/>\n330<br \/>\n2300<br \/>\n1750<br \/>\n2300<br \/>\n2200<br \/>\n2100<\/p>\n<p>300<br \/>\n\u2013<br \/>\n380<br \/>\n2200<br \/>\n1800<br \/>\n2400<br \/>\n2250<br \/>\n2150<\/p>\n<p>400<br \/>\n\u2013<br \/>\n410<br \/>\n2200<br \/>\n1750<br \/>\n2600<br \/>\n2000<br \/>\n2000<\/p>\n<p>500<br \/>\n\u2013<br \/>\n440<br \/>\n2300<br \/>\n1850<br \/>\n2700<br \/>\n1900<br \/>\n2212<\/p>\n<p>600<br \/>\n\u2013<br \/>\n460<br \/>\n2400<br \/>\n1800<br \/>\n2500<br \/>\n1700<br \/>\n2519<\/p>\n<p>700<br \/>\n\u2013<br \/>\n460<br \/>\n2400<br \/>\n1600<br \/>\n2490<br \/>\n1550<br \/>\n2607<\/p>\n<p>800<br \/>\n\u2013<br \/>\n460<br \/>\n2400<br \/>\n1600<br \/>\n2540<br \/>\n1400<br \/>\n2553<\/p>\n<p>900<br \/>\n\u2013<br \/>\n460<br \/>\n2300<br \/>\n1600<br \/>\n2472<br \/>\n1200<br \/>\n2567<\/p>\n<p>1000<br \/>\n\u2013<br \/>\n475<br \/>\n2300<br \/>\n1700<br \/>\n2485<br \/>\n1150<br \/>\n2439<\/p>\n<p>1500<br \/>\n\u2013<br \/>\n490<br \/>\n2400<br \/>\n1550<br \/>\n2620<br \/>\n900<br \/>\n2479<\/p>\n<p>2000<br \/>\n\u2013<br \/>\n350<br \/>\n2400<br \/>\n1400<br \/>\n2396<br \/>\n550<br \/>\n2200<\/p>\n<p>2500<br \/>\n\u2013<br \/>\n280<br \/>\n2100<br \/>\n1300<br \/>\n2453<br \/>\n490<br \/>\n2262<\/p>\n<p>3000<br \/>\n\u2013<br \/>\n280<br \/>\n1900<br \/>\n1250<br \/>\n2502<br \/>\ngro\u00dfe Streuung<br \/>\n2138<\/p>\n<p>5000<br \/>\n\u2013<br \/>\ngro\u00dfe Streuung<br \/>\n1600<br \/>\n1100<br \/>\n2519<br \/>\n\u2013<br \/>\n2235<\/p>\n<p>8000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n1200<br \/>\ngro\u00dfe Streuung<br \/>\n2451<br \/>\n\u2013<br \/>\n2100<\/p>\n<p>10\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\ngro\u00dfe Streuung<br \/>\n\u2013<br \/>\n2200<br \/>\n\u2013<br \/>\n2200<\/p>\n<p>11\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n2200<br \/>\n\u2013<br \/>\n2122<\/p>\n<p>12\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n970<br \/>\n\u2013<br \/>\n1958<\/p>\n<p>13\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n730<br \/>\n\u2013<br \/>\n1897<\/p>\n<p>14\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n590<br \/>\n\u2013<br \/>\n1466<\/p>\n<p>15\u00a0000<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n\u2013<br \/>\n532<br \/>\n\u2013<br \/>\n1281<\/p>\n<p>\nAus dem Diagramm und der Tabelle ist ersichtlich, dass bei \u00fcber 8000 gleichzeitigen Anfragen nur noch zwei Akteure \u00fcbrig bleiben: pre-fork und epoll. Mit zunehmender Last funktioniert der serverbasierte Poll schlechter als der Threaded. Die Architektur mit der vorzeitigen Erstellung von Threads stellt einen ernsthaften Wettbewerb f\u00fcr epoll dar: Das ist ein Zeichen daf\u00fcr, wie gut der Linux-Kernel eine gro\u00dfe Anzahl von Threads plant.<\/p>\n<h1>Quellcode von ZeroHTTPd<\/h1>\n<p>\nQuellcode von ZeroHTTPd <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/shuveb\/zerohttpd\">hier<\/a><\/noindex>. F\u00fcr jede Architektur gibt es ein separates Verzeichnis.<\/p>\n<pre>ZeroHTTPd\n\u2502\n\u251c\u2500\u2500 01_iterativ\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 02_forking\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 03_pre-forking\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 04_threading\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 05_pre-threading\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 06_poll\n\u2502   \u251c\u2500\u2500 main.c\n\u251c\u2500\u2500 07_epoll\n\u2502    \u2514\u2500\u2500 main.c\n\u251c\u2500\u2500 Makefile\n\u251c\u2500\u2500 public\n\u2502   \u251c\u2500\u2500 index.html\n\u2502   \u2514\u2500\u2500 tux.png\n\u2514\u2500\u2500 templates\n    \u2514\u2500\u2500 guestbook\n        \u2514\u2500\u2500 index.html<\/pre>\n<p>\nNeben sieben Verzeichnissen f\u00fcr alle Architekturen gibt es im Stammverzeichnis noch zwei weitere: public und templates. Im ersten Verzeichnis befindet sich die Datei index.html und das Bild des ersten Screenshots. Dort k\u00f6nnen andere Dateien und Ordner abgelegt werden, und ZeroHTTPd sollte diese statischen Dateien problemlos ausliefern. Wenn der Pfad im Browser mit dem Pfad im Verzeichnis public \u00fcbereinstimmt, sucht ZeroHTTPd in diesem Verzeichnis nach der Datei index.html. Der Inhalt f\u00fcr das G\u00e4stebuch wird dynamisch generiert. Es gibt nur die Hauptseite, deren Inhalt auf der Datei 'templates\/guestbook\/index.html' basiert. In ZeroHTTPd k\u00f6nnen dynamische Seiten leicht hinzugef\u00fcgt werden, um Erweiterungen zu erm\u00f6glichen. Die Idee ist, dass Benutzer in diesem Verzeichnis Vorlagen hinzuf\u00fcgen und ZeroHTTPd nach Bedarf erweitern k\u00f6nnen.<\/p>\n<p>Um alle sieben Server zu erstellen, starten Sie <code>make all<\/code> aus dem Stammverzeichnis \u2013 und alle Builds werden in diesem Verzeichnis erscheinen. Ausf\u00fchrbare Dateien suchen die Verzeichnisse public und templates in dem Verzeichnis, aus dem sie gestartet werden.<\/p>\n<h1>Linux-API<\/h1>\n<p>\nUm die Informationen in diesem Artikelzyklus zu verstehen, m\u00fcssen Sie sich nicht gut mit der Linux-API auskennen. Ich empfehle jedoch, mehr zu diesem Thema zu lesen, da es im Internet viele Informationsressourcen gibt. Obwohl wir einige Kategorien der Linux-API behandeln werden, werden wir uns haupts\u00e4chlich auf Prozesse, Threads, Ereignisse und den Netzwerk-Stack konzentrieren. Neben B\u00fcchern und Artikeln \u00fcber die Linux-API empfehle ich auch, die Man-Seiten f\u00fcr Systemaufrufe und verwendete Bibliotheksfunktionen zu lesen.<\/p>\n<h1>Leistung und Skalierbarkeit<\/h1>\n<p>\nEine Anmerkung zur Leistung und Skalierbarkeit. Theoretisch gibt es keinen direkten Zusammenhang zwischen ihnen. Sie k\u00f6nnen einen Webdienst haben, der sehr gut funktioniert und eine Reaktionszeit von wenigen Millisekunden hat, der jedoch \u00fcberhaupt nicht skalierbar ist. Ebenso kann es eine schlecht funktionierende Webanwendung geben, die mehrere Sekunden f\u00fcr eine Antwort ben\u00f6tigt, die jedoch auf Dutzende skalierbar ist, um Zehntausende gleichzeitiger Benutzer zu verarbeiten. Dennoch ist die Kombination aus hoher Leistung und Skalierbarkeit eine sehr starke Kombination. Hochleistungsanwendungen nutzen im Allgemeinen die Ressourcen effizient und bedienen so mehr gleichzeitige Benutzer auf dem Server, w\u00e4hrend die Kosten gesenkt werden.<\/p>\n<h1>CPU- und I\/O-Aufgaben<\/h1>\n<p>\nSchlie\u00dflich gibt es bei Berechnungen immer zwei m\u00f6gliche Arten von Aufgaben: f\u00fcr I\/O und CPU. Das Abrufen von Anfragen \u00fcber das Internet (Netzwerkeingabe- und -ausgabe), die Verwaltung von Dateien (Netzwerk- und Festplatteneingabe- und -ausgabe) sowie die Kommunikation mit einer Datenbank (Netzwerk- und Festplatteneingabe- und -ausgabe) sind alles I\/O-Aktionen. Einige Datenbankanfragen k\u00f6nnen die CPU etwas belasten (z. B. Sortieren, Berechnung des Durchschnitts von einer Million Ergebnissen usw.). Die meisten Webanwendungen sind hinsichtlich des maximal m\u00f6glichen I\/O begrenzt, w\u00e4hrend der Prozessor selten voll ausgelastet ist. Wenn Sie sehen, dass bei einer bestimmten I\/O-Aufgabe viel CPU verwendet wird, ist das wahrscheinlich ein Zeichen f\u00fcr eine schlechte Anwendungsarchitektur. Das kann bedeuten, dass CPU-Ressourcen f\u00fcr das Prozessmanagement und das Kontextwechseln aufgewendet werden \u2013 und das ist nicht besonders n\u00fctzlich. Wenn Sie etwas wie Bildverarbeitung, Audiokonvertierung oder maschinelles Lernen durchf\u00fchren, dann ben\u00f6tigt die Anwendung leistungsstarke CPU-Ressourcen. F\u00fcr die meisten Anwendungen trifft das jedoch nicht zu.<\/p>\n<h1>Mehr \u00fcber Serverarchitekturen<\/h1>\n<p><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-i-iterative-servers\/\">Teil I. Iterative Architektur<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-ii-forking-servers\/\">Teil II. Fork-Server<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-iii-preforked-servers\/\">Teil III. Pre-Fork-Server<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-iv-threaded-servers\/\">Teil IV. Server mit Ausf\u00fchrungsstr\u00e4ngen<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-v-pre-threaded-servers\/\">Teil V. Server mit vorab erzeugten Str\u00e4ngen<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-vi-polling-servers\/\">Teil VI. Poll-basierte Architektur<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/unixism.net\/2019\/04\/28\/linux-applications-performance-part-vii-epoll-servers\/\">Teil VII. Epoll-basierte Architektur<\/a><\/noindex><\/li>\n<\/ol>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/455212\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u044b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e, \u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u043b\u044c\u0432\u0438\u043d\u0443\u044e \u0434\u043e\u043b\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 HTTP. \u0418\u0437\u0443\u0447\u0430\u044f \u043d\u044e\u0430\u043d\u0441\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0443\u0434\u0435\u043b\u044f\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u0430\u043b\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0433\u0434\u0435 \u044d\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f. \u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (Dev) \u0438 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 (Ops) \u043b\u0438\u0448\u044c \u0443\u0445\u0443\u0434\u0448\u0430\u043b\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e. \u041d\u043e \u0441 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u044b DevOps \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u043d\u0435\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35106","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u044b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e, \u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u043b\u044c\u0432\u0438\u043d\u0443\u044e \u0434\u043e\u043b\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 HTTP.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 Linux. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u044b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e, \u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u043b\u044c\u0432\u0438\u043d\u0443\u044e \u0434\u043e\u043b\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 HTTP.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:02:22+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:02:22+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Leistung von Netzwerkanwendungen unter Linux. Einf\u00fchrung | ProHoster","description":"Webanwendungen werden heutzutage \u00fcberall eingesetzt, und unter allen Transportprotokollen macht HTTP den gr\u00f6\u00dften Anteil aus.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 Linux. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 | ProHoster","og:description":"\u0412\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u044b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e, \u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u043b\u044c\u0432\u0438\u043d\u0443\u044e \u0434\u043e\u043b\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 HTTP.","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/proizvoditelnost-setevyh-prilozhenij-linux-vvedenie","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:02:22+00:00","article:modified_time":"2019-10-31T19:02:22+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35106","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 21:51:33","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:09:55","updated":"2026-01-21 21:51:33","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/35106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=35106"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/35106\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=35106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=35106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=35106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}