Ich lese die Dokumente des Cluster-Moduls in Node.js:
Ссылка
Es behauptet folgendes:
Wenn mehrere Prozesse alle auf demselben Basiswert basieren Ressource, das Betriebssystem Load-Balances über sie sehr effizient.
Das hört sich vernünftig an, aber selbst nach ein paar Stunden Googeln habe ich keinen Artikel oder irgendetwas gefunden, was es bestätigen würde, oder zu erklären, wie diese Load-Balancing-Logik im Betriebssystem funktioniert.
Welche Betriebssysteme machen diese effektive Lastverteilung?
"Load Balancing" ist vielleicht ein bisschen schlechte Wahl der Wörter, im Wesentlichen ist es nur eine Frage, wie das Betriebssystem wählen, welchen Prozess aufzuwachen und / oder als nächstes laufen. Im Allgemeinen versucht der Prozess-Scheduler den Prozess zu wählen, basierend auf Kriterien wie dem Geben eines gleichen Anteils von CPU-Zeit zu Prozessen mit gleicher Priorität, CPU- / Speicher-Lokalität (keine Prozesse um die CPU herum bouncen), etc. Jedenfalls durch Googeln Sie werden viel über Prozessablaufplanungsalgorithmen und -implementierungen lesen können.
Nun, für den speziellen Fall von accept () hängt das auch davon ab, wie das OS Aufweckprozesse implementiert, die auf accept () warten.
Eine einfache Implementierung besteht darin, jeden Prozess, der beim accept () - Aufruf blockiert wird, aufzuwecken und dann dem Scheduler zu erlauben, die Reihenfolge zu wählen, in der er ausgeführt werden soll.
Das Obige ist einfach, führt aber zu einem "donnernden Herden" -Problem, da nur der erste Prozess die Verbindung akzeptiert, die anderen wieder blockieren. Ein ausgefeilterer Ansatz besteht darin, dass das OS nur einen Prozess aufweckt; hier kann die Wahl, welcher Prozess aufzuwachen ist, durch Fragen des Schedulers oder z.B. indem Sie den ersten Prozess in der blocked-on-accept () - for-this-socket-Liste auswählen. Letzteres ist das, was Linux seit einem Jahrzehnt oder mehr zurück tut, basierend auf dem Link bereits von anderen gepostet.
Beachten Sie, dass dies nur zum Blockieren von accept () funktioniert; für nicht-blocking accept () (was bin ich sicher, was node.js macht) wird das Problem, auf welchen Prozess blockiert in select () / poll () / was auch immer, um das Ereignis zu liefern. Die Semantik von poll () / select () verlangt tatsächlich, dass alle aufgeweckt werden, so dass Sie das donnernde Herdenproblem wieder haben. Für Linux und wahrscheinlich in ähnlicher Weise für andere Systeme mit systemspezifischen Hochleistungspolling-Schnittstellen ist es auch möglich, die donnernde Herde zu vermeiden, indem ein einzelnes geteiltes epoll fd und flankengetriggerte Ereignisse verwendet werden. In diesem Fall wird das Ereignis nur an einen der Prozesse übergeben, die auf epoll_wait () blockiert sind. Ich denke, dass, ähnlich wie das Blockieren von accept (), die Wahl des Prozesses, zu dem das Ereignis geliefert wird, nur das erste in der Liste der Prozesse ist, die auf epoll_wait () für dieses bestimmte epoll fd blockiert sind.
Also zumindest für Linux, sowohl für das Blockieren von accept () als auch für das nicht-blockierende accept () mit flankengetriggertem epoll, gibt es bei der Auswahl des aufzuweckenden Prozesses keine Planung per se. Aber OTOH, die Arbeitslast wird wahrscheinlich ziemlich gleichmäßig zwischen den Prozessen ausgeglichen sein, da im Wesentlichen das System die Prozesse in der Reihenfolge, in der sie ihre aktuelle Arbeit beenden, zurückkreist und zurück zum Blockieren auf epoll_wait () geht.
Tags und Links sockets node.js concurrency networking