Serwery Indy – EPOLL Linux (3/3)

· Funkcje

Od sgcWebSockets 2022.9.0 dostępny jest nowy IOHandler dla systemu Linux. Używając EPOLL możesz uniknąć problemu "jeden-wątek-na-klienta", gdzie wydajność znacznie spada przy większej liczbie połączeń obsługiwanych przez serwer. IOCP udostępnia kilka wątków obsługujących wielu klientów jednocześnie. Wątki są zawieszone i nie zużywają cykli procesora, dopóki nie ma czegoś do przetworzenia.

EPOLL IOHandler jest dostępny tylko w pakiecie sgcWebSockets Enterprise.


Konfiguracja

EPOLL dla systemu Linux to API umożliwiające obsługę tysięcy połączeń przy użyciu ograniczonej puli wątków, zamiast dedykowania osobnego wątku każdemu połączeniu, jak domyślnie robi to Indy.

Aby włączyć EPOLL dla serwerów Indy, przejdź do właściwości IOHandlerOptions i wybierz iohEPOLL jako typ 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 to wątki używane dla asynchronicznych żądań EPOLL (operacji nakładkowych). Domyślnie wartość wynosi zero, co oznacza, że liczba wątków jest obliczana na podstawie liczby procesorów (z wyjątkiem Delphi 7 i 2007, gdzie liczba wątków wynosi 32, ponieważ funkcja cpucount nie jest obsługiwana). Możesz ręcznie dostosować liczbę wątków.

2. WorkOpThreads należy włączyć tylko wtedy, gdy chcesz, aby połączenia były zawsze przetwarzane w tym samym wątku. Przy użyciu EPOLL żądania są przetwarzane przez pulę wątków i każde żądanie (dla tego samego połączenia) może być obsłużone przez różne wątki. Jeśli chcesz obsługiwać każde połączenie w tym samym wątku, ustaw w WorkOpThreads liczbę wątków przeznaczonych do obsługi tych żądań. Wpływa to na wydajność serwera i zalecane jest ustawianie wartości większej od zera tylko gdy ta funkcja jest niezbędna.

Włączenie EPOLL dla serwerów Linux jest zalecane, gdy potrzebujesz obsługiwać tysiące połączeń. Jeśli twój serwer obsługuje maksymalnie 100 jednoczesnych połączeń, możesz pozostać przy domyślnym modelu wątków Indy.

Test wydajności

Prosty test pokaże różnice między modelem wątków Indy a EPOLL. Test połączy się z serwerem używając protokołu WebSocket, a zużycie procesora i pamięci zostanie przedstawione w poniższej tabeli. Procentowe zużycie procesora jest mierzone, gdy serwer jest w stanie bezczynności.

Liczba połączeń Indy IOHandler domyślny Indy IOHandler EPOLL
100 1% (1.4MB) 0% (1.4MB)
5004% (5.6MB)0% (4.8MB)
100010% (10.5MB)0% (8.9MB)
1500-- (Failed)0% (13.3MB)
2000-- (Failed)0% (17.4MB)

Serwer Indy nie mógł obsłużyć więcej niż 1024 jednoczesnych połączeń ze względu na ograniczenie metody Select. Porównując wyniki do 1000 połączeń, domyślny serwer Indy używał więcej procesora i więcej RAM niż serwer EPOLL. Serwer EPOLL nie używał procesora w stanie bezczynności, a zużycie pamięci było również niższe.

Kolejny test mierzy czas potrzebny do połączenia X klientów.

Liczba połączeń Indy IOHandler domyślny Indy IOHandler EPOLL
1000 16.5 seconds 9.49 seconds
10000-- (Failed)1min 55 seconds

Testy zostały przeprowadzone na Ubuntu 20.0.4 z 2 procesorami i 8 GB RAM uruchomionym na maszynie wirtualnej.

Dokumentacja EPOLL

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

Świetne projekty Delphi implementujące EPOLL

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