EPOLL

Unterstützt von

 

TsgcWebSocketServer

TsgcWebSocketHTTPServer

 

*Erfordert die sgcWebSockets Enterprise Edition.

 

EPOLL für Linux ist eine API, die es ermöglicht, Tausende von Verbindungen mit einem begrenzten Pool von Threads zu verarbeiten, anstatt einen Thread pro Verbindung zu verwenden, wie es Indy standardmäßig tut.

Um EPOLL für Indy-Server zu aktivieren, gehen Sie zur Eigenschaft IOHandlerOptions und wählen Sie iohIEPOLL als IOHandler-Typ aus.


Server.IOHandlerOptions.IOHandlerType := iohEPOLL;
Server.IOHandlerOptions.EPOLL.EPOLLThreads := 0;
Server.IOHandlerOptions.EPOLL.WorkOpThreads := 0;
Server.IOHandlerOptions.EPOLL.PartialRequestTimeout := 0;
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Enabled := True;
Server.IOHandlerOptions.KeepAliveTimeout := 120;

 

EPOLLThreads sind die Threads, die für EPOLL-asynchrone Anfragen (überlappte Operationen) verwendet werden; standardmäßig ist der Wert null, was bedeutet, dass die Anzahl der Threads anhand der Anzahl der Prozessoren berechnet wird (außer bei Delphi 7 und 2007, wo die Anzahl der Threads auf 32 gesetzt wird, da die Funktion cpucount nicht unterstützt wird). Sie können die Anzahl der Threads manuell anpassen.

WorkOpThreads legt die Mindestanzahl an Worker-Threads fest, die zur Verarbeitung von Anfragen bereitgehalten werden, standardmäßig 0. Ein EPOLL-Thread erkennt nur, dass ein Socket bereit ist, und übergibt die Arbeit an diesen Pool, sodass er niemals durch einen langsamen Client blockiert wird. Der Pool wächst bei Bedarf bis zu einem festen Maximum, sobald alle Worker bereits beschäftigt sind, er muss also nicht im Voraus dimensioniert werden. Erhöhen Sie diesen Wert nur, wenn der Pool schon vor der ersten Anfrage bereitstehen soll, was die Kosten für das Erzeugen von Threads während eines anfänglichen Ansturms von Verbindungen vermeidet.

Geändert in 2026.9.0. WorkOpThreads band früher jede Verbindung fest an einen dieser Threads, sodass alle Anfragen einer Verbindung im selben Thread liefen, und WorkOpRoundRobin bestimmte, wie neue Verbindungen auf diese Threads verteilt wurden. Diese feste Bindung wurde entfernt: Eine Verbindung, die auf den Rest einer Anfrage wartete, blockierte alle anderen Verbindungen, die demselben Thread zugewiesen waren, und legte den Server lahm. Anfragen derselben Verbindung können jetzt in unterschiedlichen Threads laufen. Bei allem, was pro Thread gehalten wird, etwa einer Datenbankverbindung oder einem Thread-lokalen Cache, darf daher nicht mehr davon ausgegangen werden, dass es einer Verbindung folgt. WorkOpRoundRobin existiert nicht mehr. Entfernen Sie die Eigenschaft aus Ihrem Code, und wenn Sie sie im Object Inspector aktiviert hatten, löschen Sie auch die Zeile WorkOpRoundRobin aus der .dfm-Datei des Formulars, sonst wird das Formular nicht geladen.

PartialRequestTimeout lässt den Server auf den Rest eines HTTP-Anfragetexts warten, dessen Länge bereits bekannt ist, in Millisekunden und standardmäßig 0, was die Funktion deaktiviert. Ohne diese Option wird ein Anfragetext, der nicht vollständig innerhalb eines einzigen Bereitschaftsereignisses eintrifft, zum Beispiel ein großer POST, der in mehreren Paketen gesendet wird, stillschweigend verworfen und die Verbindung ohne Antwort geschlossen. Die Wartezeit läuft niemals in einem EPOLL-Thread ab, der viele Verbindungen bedient und niemals blockieren darf, sondern in dem oben beschriebenen Worker-Pool, der bei Bedarf bis zu einem festen Maximum wächst, sodass ein langsamer oder nicht reagierender Client ihn nicht erschöpfen und die übrigen Verbindungen aufhalten kann.

TCPKeepAlive ermöglicht es dem Betriebssystem, inaktive Verbindungen zu prüfen und einen Peer zu erkennen, der stillschweigend verschwunden ist (standardmäßig deaktiviert). Wenn TCPKeepAlive.Enabled auf True gesetzt ist, beginnt das Betriebssystem eine Verbindung zu prüfen, nachdem sie TCPKeepAlive.Time Sekunden lang inaktiv war (standardmäßig 60), und wiederholt dies alle TCPKeepAlive.Interval Sekunden (standardmäßig 10), bis der Peer antwortet oder die Verbindung abgebrochen wird.

KeepAliveTimeout schließt jede Verbindung, die länger als die angegebene Anzahl von Sekunden im Leerlauf war (standardmäßig 0, was deaktiviert bedeutet). Betroffen sind nur Verbindungen im Leerlauf, eine Anfrage, die gerade gelesen wird, oder eine Antwort, die gerade geschrieben wird, wird von diesem Timeout niemals unterbrochen. Das kommt dem am nächsten, wie der standardmäßige IOHandler mit einem Thread pro Verbindung eine stumme Verbindung freigibt, und es hängt weder vom Betriebssystem noch von einer Mitwirkung des Peers ab.

 

Das Aktivieren von EPOLL für Linux-Server wird empfohlen, wenn Sie Tausende von Verbindungen verarbeiten müssen. Wenn Ihr Server nur maximal 100 gleichzeitige Verbindungen verarbeitet, können Sie beim Standard-Indy-Thread-Modell bleiben.

 

 

OnDisconnect-Ereignis nicht ausgelöst

 

EPOLL funktioniert anders als der Standard-Indy-IOHandler. Mit dem Standard-Indy-IOHandler läuft jede Verbindung in einem Thread, und diese Threads laufen ständig und prüfen, ob die Verbindung aktiv ist, sodass eine Trennung in kurzer Zeit gemeldet wird.

 

EPOLL funktioniert anders, es gibt einen Thread-Pool, der alle Verbindungen verwaltet, statt 1 Thread = 1 Verbindung, wie es Indy standardmäßig macht. Bei EPOLL besteht die einzige Möglichkeit, festzustellen, ob eine Verbindung noch aktiv ist, darin, in den Socket zu schreiben. Tritt dabei ein Fehler auf, bedeutet das, dass die Verbindung geschlossen ist. Es gibt 3 Optionen, um Trennungen zu erkennen:

 

1. Wenn Sie TsgcWebSocketClient verwenden, können Sie es in der Eigenschaft Options aktivieren, CleanDisconnect := True (standardmäßig deaktiviert). Wenn es aktiviert ist, sendet der Client vor dem Trennen eine Nachricht, die den Server über die Verbindungstrennung informiert, sodass der Server diese Nachricht empfängt und das Ereignis OnDisconnect ausgelöst wird.

2. Sie können heartbeat auf der Server-Seite aktivieren, zum Beispiel alle 60 Sekunden, sodass versucht wird, einen Ping an alle verbundenen Clients zu senden, und wenn ein Client getrennt ist, wird OnDisconnect aufgerufen.

3. Sie können TCPKeepAlive aktivieren und/oder KeepAliveTimeout in den IOHandlerOptions des Servers setzen. Damit kann der Server selbst einen Peer erkennen, der verstummt ist, zum Beispiel weil der Client abgestürzt ist oder die Netzwerkverbindung abgebrochen wurde, ohne eine Close-Nachricht zu senden, und die Verbindung schließen, ohne darauf angewiesen zu sein, dass der Client etwas sendet.

 

Linux Connections Limit

 

Wenn Sie die Anzahl der gleichzeitig offenen Verbindungen erhöhen möchten, verwenden Sie den folgenden Befehl

 

ulimit -n 10000

 

Der vorherige Befehl setzt die maximale Anzahl offener Dateideskriptoren auf 10000