Servidores Indy - IOCP Windows (2 / 3)

· Características

Desde sgcWebSockets 2022.9.0 el IOHandler IOCP del servidor Indy se ha reescrito desde cero y se ha mejorado el rendimiento. El IOHandler IOCP solo está disponible en el paquete sgcWebSockets Enterprise.

Usando IOCP puedes evitar el problema de "un hilo por cliente", donde el rendimiento disminuye mucho a medida que el servidor gestiona más conexiones. IOCP proporciona unos pocos hilos que gestionan múltiples clientes. Los hilos están suspendidos y no usan ciclos de CPU hasta que hay algo que procesar.

Configuración 

Para activar IOCP en los servidores Indy, ve a la propiedad IOHandlerOptions y selecciona iohIOCP como IOHandler Type. 

Server.IOHandlerOptions.IOHandlerType := iohIOCP;
Server.IOHandlerOptions.IOCP.IOCPThreads := 0; // the number of IOCP threads will be calculated automatically using the number of processors.
Server.IOHandlerOptions.IOCP.WorkOpThreads := 0; 

1. IOCPThreads son los hilos usados para peticiones asíncronas IOCP (operaciones overlapped); por defecto el valor es cero, lo que significa que el número de hilos se calcula usando el número de procesadores (excepto en Delphi 7 y 2007, donde el número de hilos se establece a 32 porque la función cpucount no es compatible).

2. WorkOpThreads solo debe activarse si quieres que las conexiones se procesen siempre en el mismo hilo. Al usar IOCP, las peticiones se procesan por un pool de hilos y cada petición (para la misma conexión) puede procesarse en diferentes hilos. Si quieres gestionar cada conexión en el mismo hilo, establece en WorkOpThreads el número de hilos usados para gestionar estas peticiones. Esto impacta en el rendimiento del servidor y solo se recomienda establecer un valor mayor que cero si realmente necesitas esta característica.

Activar IOCP para servidores windows está recomendado cuando necesitas gestionar miles de conexiones; si tu servidor solo gestiona 100 conexiones concurrentes como máximo, puedes quedarte con el modelo de hilos Indy por defecto.

Prueba de rendimiento 

Una prueba simple mostrará las diferencias entre el modelo de hilos Indy y IOCP. La prueba se conectará al servidor usando el protocolo websocket y se mostrará el uso de cpu y el consumo de memoria en la siguiente tabla. El % de uso de cpu es mientras el servidor está IDLE.

Núm. conexiones Indy IOHandler por defecto Indy IOCP IOHandler
100 0% (4.1MB) 0% (3.9MB)
5000% (17.1MB)0% (7.7MB)
10000% (32.2MB)0% (12.4MB)
15007.3% (46.8MB)0% (17.1MB)
200015.4% (61.6MB)0% (21.9MB)
250051.9% (76.5MB)0% (26.5MB)
300068.8% (91.7MB)0% (31.2MB)
350072.3% (106MB)0% (35.9MB)

El servidor Indy empezó a experimentar ralentizaciones con más de 3000 conexiones concurrentes, muy probablemente debido al cambio de contexto entre hilos, y el uso de cpu era muy alto mientras el servidor estaba inactivo.

El servidor IOCP no usaba CPU mientras estaba en estado idle y el consumo de memoria también era menor.

La siguiente prueba mide cuánto tiempo tarda en conectar 3000 clientes; cada uno envía un mensaje al conectarse al servidor y el servidor le hace echo a este mensaje.

Indy IOHandler por defecto Indy IOCP IOHandler
Conectar 3000 clientes y echo del mensaje 15.32 segundos 6.89 segundos

Las pruebas de rendimiento se han hecho en un Windows Server 2022 con 16 cores y 32GB de RAM.