it-swarm.com.de

Wie "lauschen" Webserver auf IP-Adressen, unterbrechen oder rufen ab?

Ich versuche, die Details von Webservern zu verstehen. Ich frage mich, ob ein Server, wie Apache, ständig nach neuen Anfragen fragt oder ob er von einem Interrupt-System funktioniert. Wenn es sich um einen Interrupt handelt, was löst den Interrupt aus, ist es der Netzwerkkartentreiber?

87
user2202911

Die kurze Antwort lautet: eine Art Interrupt-System. Im Wesentlichen verwenden sie blockierende E/A, dh sie schlafen (blockieren), während sie auf neue Daten warten.

  1. Der Server erstellt einen Listening-Socket und blockiert ihn, während er auf neue Verbindungen wartet. Während dieser Zeit versetzt der Kernel den Prozess in einen unterbrechbaren Ruhezustand und führt andere Prozesse aus. Dies ist ein wichtiger Punkt: Wenn die Prozessabfrage kontinuierlich durchgeführt wird, wird die CPU verschwendet. Der Kernel kann die Systemressourcen effizienter nutzen, indem er den Prozess blockiert, bis Arbeit für ihn zu erledigen ist.

  2. Wenn neue Daten im Netzwerk ankommen, gibt die Netzwerkkarte einen Interrupt aus.

  3. Nachdem die Netzwerkkarte unterbrochen wurde, liest der Kernel über den Netzwerkkartentreiber die neuen Daten von der Netzwerkkarte und speichert sie im Speicher. (Dies muss schnell erledigt werden und wird in der Regel im Interrupt-Handler erledigt.)

  4. Der Kernel verarbeitet die neu eingetroffenen Daten und ordnet sie einem Socket zu. Ein Prozess, der auf diesem Socket blockiert wird, wird als ausführbar markiert, was bedeutet, dass er jetzt ausgeführt werden kann. Es wird nicht unbedingt sofort ausgeführt (der Kernel entscheidet sich möglicherweise dafür, andere Prozesse noch auszuführen).

  5. In seiner Freizeit wird der Kernel den blockierten Webserver-Prozess aktivieren. (Da es jetzt lauffähig ist.)

  6. Der Webserver-Prozess wird so ausgeführt, als ob keine Zeit verstrichen wäre. Sein blockierender Systemaufruf kehrt zurück und verarbeitet alle neuen Daten. Fahren Sie dann mit Schritt 1 fort.

181
Greg Bowser

Es gibt ziemlich viele "niedrigere" Details.

Stellen Sie sich zunächst vor, der Kernel verfügt über eine Liste von Prozessen. Einige dieser Prozesse werden zu einem bestimmten Zeitpunkt ausgeführt, andere nicht. Der Kernel lässt jedem laufenden Prozess einen Teil der CPU-Zeit zu, unterbricht ihn dann und wechselt zum nächsten. Wenn es keine ausführbaren Prozesse gibt, gibt der Kernel wahrscheinlich eine Anweisung wie HLT an die CPU aus, die die CPU anhält, bis ein Hardware-Interrupt auftritt.

Irgendwo auf dem Server gibt es einen Systemaufruf , der besagt "Gib mir etwas zu tun". Es gibt zwei Kategorien von Möglichkeiten, wie dies durchgeführt werden kann. Im Fall von Apache ruft er accept auf einem Socket auf, den Apache zuvor geöffnet hat, und überwacht wahrscheinlich Port 80. Der Kernel verwaltet eine Warteschlange mit Verbindungsversuchen und fügt diese jedes Mal hinzu, wenn ein TCP SYN wird empfangen. Wie der Kernel weiß, dass eine TCP SYN empfangen wurde, hängt vom Gerätetreiber ab. Bei vielen Netzwerkkarten liegt wahrscheinlich ein Hardware-Interrupt vor, wenn Netzwerkdaten empfangen werden.

accept fordert den Kernel auf, den nächsten Verbindungsaufbau an mich zurückzugeben. Wenn die Warteschlange nicht leer war, wird accept sofort zurückgegeben. Wenn die Warteschlange leer ist, wird der Prozess (Apache) aus der Liste der ausgeführten Prozesse entfernt. Wenn später eine Verbindung hergestellt wird, wird der Vorgang fortgesetzt. Dies wird als "Blockieren" bezeichnet, da accept() für den Prozess, der es aufruft, wie eine Funktion aussieht, die erst zurückkehrt, wenn ein Ergebnis vorliegt, das in einiger Zeit vorliegen könnte. Während dieser Zeit kann der Prozess nichts anderes tun.

Sobald accept zurückkehrt, weiß Apache, dass jemand versucht, eine Verbindung herzustellen. Anschließend wird fork aufgerufen, um den Apache-Prozess in zwei identische Prozesse aufzuteilen. Einer dieser Prozesse verarbeitet die HTTP-Anforderung, der andere ruft accept erneut auf, um die nächste Verbindung herzustellen. Daher gibt es immer einen Master-Prozess, der nur accept aufruft und Unterprozesse erzeugt, und dann gibt es einen Unterprozess für jede Anforderung.

Dies ist eine Vereinfachung: Es ist möglich, dies mit Threads anstelle von Prozessen zu tun, und es ist auch möglich, zuvor fork zu setzen, damit ein Worker-Prozess bereit ist, wenn eine Anforderung empfangen wird, wodurch der Startaufwand verringert wird. Abhängig davon, wie Apache konfiguriert ist, kann es eines dieser Dinge tun.

Dies ist die erste allgemeine Kategorie, und sie wird Blockieren von IO genannt, da Systemaufrufe wie accept und read und write, die auf Sockets arbeiten, den Prozess anhalten, bis sie etwas haben zurückgeben.

Die andere Möglichkeit nennt sich nicht blockierend oder ereignisbasiert oder asynchrones E/A . Dies wird mit Systemaufrufen wie select oder epoll implementiert. Diese tun jeweils dasselbe: Sie geben ihnen eine Liste von Sockets (oder allgemein Dateideskriptoren) und was Sie damit tun möchten, und der Kernel blockiert, bis er bereit ist, eines dieser Dinge zu tun.

Bei diesem Modell können Sie dem Kernel (mit epoll) mitteilen, "ob eine neue Verbindung auf Port 80 besteht oder ob neue Daten auf einer dieser 9471 anderen Verbindungen gelesen werden sollen, die ich geöffnet habe". epoll blockiert, bis eines dieser Dinge fertig ist, dann machst du es. Dann wiederholst du. Systemaufrufe wie accept und read und write blockieren niemals, zum Teil, weil epoll Ihnen immer dann, wenn Sie sie aufrufen, mitgeteilt hat, dass sie bereit sind, sodass es keinen Grund zum Blockieren gibt, und auch, wenn Sie den Socket oder die von Ihnen angegebene Datei öffnen Wenn Sie möchten, dass sie nicht blockiert werden, schlagen diese Aufrufe mit EWOULDBLOCK fehl, anstatt zu blockieren.

Der Vorteil dieses Modells ist, dass Sie nur einen Prozess benötigen. Dies bedeutet, dass Sie nicht für jede Anforderung eine Stapel- und Kernelstruktur zuweisen müssen. Nginx und HAProxy verwenden dieses Modell, und es ist ein großer Grund, warum sie mit so viel mehr Verbindungen als Apache auf ähnlicher Hardware umgehen können.

9
Phil Frost