Indy Servers - EPOLL Linux (3 / 3)

· Fonctionnalités

Depuis sgcWebSockets 2022.9.0, un nouveau IOHandler pour Linux est disponible. Avec EPOLL, tu peux éviter le problème « un thread par client » qui dégrade fortement les performances à mesure que le serveur gère plus de connexions. IOCP fournit quelques threads qui gèrent plusieurs clients. Les threads sont suspendus et n'utilisent pas de cycles CPU tant qu'il n'y a rien à traiter.

L'IOHandler EPOLL n'est disponible que dans le package sgcWebSockets Enterprise.


Configuration 

EPOLL pour Linux est une API qui permet de gérer des milliers de connexions avec un pool limité de threads, au lieu d'utiliser un thread par connexion comme Indy le fait par défaut.

Pour activer EPOLL sur les serveurs Indy, va dans la propriété IOHandlerOptions et sélectionne iohIEPOLL comme type d'IOHandler.

Server.IOHandlerOptions.IOHandlerType := iohEPOLL;
Server.IOHandlerOptions.EPOLL.EPOLLThreads := 0; // the number of EPOLL threads will be calculated automatically using the number of processors.
Server.IOHandlerOptions.EPOLL.WorkOpThreads := 0;

1. EPOLLThreads sont les threads utilisés pour les requêtes asynchrones EPOLL (opérations overlapped). Par défaut, la valeur est zéro, ce qui signifie que le nombre de threads est calculé en fonction du nombre de processeurs (sauf pour Delphi 7 et 2007 où le nombre de threads est défini à 32 parce que la fonction cpucount n'est pas prise en charge). Tu peux ajuster manuellement le nombre de threads.

2. WorkOpThreads doit seulement être activé si tu veux que les connexions soient toujours traitées dans le même thread. Avec EPOLL, les requêtes sont traitées par un pool de threads, et chaque requête (pour la même connexion) peut être traitée dans différents threads. Si tu veux gérer chaque connexion dans le même thread, définis dans WorkOpThreads le nombre de threads utilisés pour gérer ces requêtes. Cela impacte les performances du serveur ; il n'est recommandé de définir une valeur supérieure à zéro que si tu as besoin de cette fonctionnalité.

Activer EPOLL sur les serveurs Linux est recommandé lorsque tu dois gérer des milliers de connexions. Si ton serveur ne gère que 100 connexions simultanées au maximum, tu peux rester avec le modèle de threads Indy par défaut.

Test de performances 

Un test simple montre les différences entre le modèle de threads Indy et EPOLL. Le test se connecte au serveur via le protocole websocket ; l'usage CPU et la consommation mémoire sont présentés dans le tableau suivant. Le pourcentage d'usage CPU est mesuré pendant que le serveur est en IDLE.

Nb. connexions Indy IOHandler par défaut Indy IOHandler EPOLL
100 1 % (1.4 Mo) 0 % (1.4 Mo)
5004 % (5.6 Mo)0 % (4.8 Mo)
100010 % (10.5 Mo)0 % (8.9 Mo)
1500-- (Échec)0 % (13.3 Mo)
2000-- (Échec)0 % (17.4 Mo)

Le serveur Indy n'a pas pu ouvrir plus de 1024 connexions simultanées, en raison de la limitation de la méthode Select à accepter plus de 1024 connexions simultanées. En comparant les résultats jusqu'à 1000 connexions, le serveur Indy par défaut utilisait plus de CPU et plus de RAM que le serveur EPOLL. Le serveur EPOLL n'utilisait pas de CPU lorsqu'il était en état idle et la consommation mémoire était également plus faible.

Le test suivant mesure le temps nécessaire pour connecter X clients.

Nb. connexions Indy IOHandler par défaut Indy IOHandler EPOLL
1000 16.5 secondes 9.49 secondes
10000-- (Échec)1 min 55 secondes

Les tests ont été réalisés sur Ubuntu 20.0.4 avec 2 processeurs et 8 Go de RAM, dans une machine virtuelle.

Documentation EPOLL

https://man7.org/linux/man-pages/man7/epoll.7.html

Excellents projets Delphi qui implémentent EPOLL

https://github.com/winddriver/Delphi-Cross-Socket
https://github.com/grijjy/GrijjyFoundation