EPOLL

Compatible con

 

TsgcWebSocketServer

TsgcWebSocketHTTPServer

 

*Requiere sgcWebSockets Enterprise Edition.

 

EPOLL para Linux es una API que permite gestionar miles de conexiones utilizando un número limitado de hilos en lugar de usar un hilo por conexión como hace Indy por defecto.

Para habilitar EPOLL en los servidores Indy, vaya a la propiedad IOHandlerOptions y seleccione iohIEPOLL como tipo de IOHandler.


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 son los hilos usados para las solicitudes asíncronas EPOLL (operaciones superpuestas); por defecto el valor es cero, lo que significa que el número de hilos se calcula usando el número de procesadores (excepto para Delphi 7 y 2007 donde el número de hilos se establece en 32 porque la función cpucount no es compatible). Puede ajustar el número de hilos manualmente.

WorkOpThreads establece el número mínimo de hilos de trabajo que se mantienen listos para procesar solicitudes, 0 por defecto. Un hilo EPOLL solo detecta que un socket está preparado y entrega el trabajo a este grupo, de modo que nunca se bloquea con un cliente lento. El grupo crece bajo demanda hasta un máximo fijo siempre que todos los hilos de trabajo ya están ocupados, por lo que no es necesario dimensionarlo de antemano. Aumente este valor solo si desea que el grupo esté ya preparado antes de la primera solicitud, lo que evita pagar el coste de crear hilos durante una ráfaga inicial de conexiones.

Cambio en 2026.9.0. WorkOpThreads solía fijar cada conexión a uno de estos hilos, de modo que todas las solicitudes de una conexión se ejecutaban en el mismo hilo, y WorkOpRoundRobin decidía cómo se repartían las nuevas conexiones entre ellos. Esa fijación se ha eliminado: una conexión que quedaba a la espera del resto de una solicitud bloqueaba a todas las demás conexiones asignadas al mismo hilo, lo que dejaba el servidor parado. Las solicitudes de una misma conexión pueden ejecutarse ahora en hilos distintos, por lo que ya no se puede dar por supuesto que aquello que se guarda por hilo, como una conexión a base de datos o una caché local del hilo, acompañe a una conexión. WorkOpRoundRobin ya no existe. Elimínelo de su código y, si lo había activado en el Object Inspector, borre también la línea WorkOpRoundRobin del .dfm del formulario; de lo contrario, el formulario no se carga.

PartialRequestTimeout permite que el servidor espere el resto de un cuerpo de solicitud HTTP cuya longitud ya conoce, en milisegundos y 0 por defecto, lo que lo desactiva. Sin esta opción, un cuerpo de solicitud que no llega completo dentro de un único evento de disponibilidad, por ejemplo un POST grande enviado en varios paquetes, se descarta silenciosamente y la conexión se cierra sin respuesta. La espera nunca se ejecuta en un hilo EPOLL, que atiende muchas conexiones y nunca debe bloquearse; se ejecuta en el grupo de hilos descrito más arriba, que crece bajo demanda hasta un máximo fijo, de modo que un cliente lento o que no responde no puede agotarlo ni retrasar al resto de conexiones.

TCPKeepAlive permite que el sistema operativo sondee las conexiones inactivas y detecte un par que ha desaparecido silenciosamente (desactivado por defecto). Cuando TCPKeepAlive.Enabled se establece en True, el sistema operativo empieza a sondear una conexión después de que haya estado inactiva durante TCPKeepAlive.Time segundos (60 por defecto), repitiendo cada TCPKeepAlive.Interval segundos (10 por defecto) hasta que el par responda o la conexión se cierre.

KeepAliveTimeout cierra cualquier conexión que haya estado inactiva durante más del número de segundos indicado (0 por defecto, lo que significa desactivado). Solo afecta a las conexiones inactivas; una solicitud que se está leyendo o una respuesta que se está escribiendo nunca se ve interrumpida por este tiempo de espera. Esta es la forma más parecida a como el IOHandler predeterminado de un hilo por conexión libera una conexión silenciosa, y no depende del sistema operativo ni de ninguna colaboración por parte del par.

 

Se recomienda habilitar EPOLL para servidores Linux cuando necesite gestionar miles de conexiones. Si su servidor solo maneja un máximo de 100 conexiones simultáneas, puede quedarse con el modelo de hilos predeterminado de Indy.

 

 

El evento OnDisconnect no se activa

 

EPOLL funciona de manera diferente al IOHandler de Indy predeterminado. Con el IOHandler predeterminado de Indy, cada conexión se ejecuta en un hilo y estos hilos están en ejecución constante comprobando si la conexión está activa, de modo que si se produce una desconexión, se notifica en un breve período de tiempo.

 

EPOLL funciona de manera diferente: existe un grupo de hilos que gestiona todas las conexiones, en lugar de 1 hilo = 1 conexión como hace Indy por defecto. Para EPOLL, la única forma de detectar si una conexión sigue activa es intentar escribir en el socket; si hay algún error, significa que la conexión está cerrada. Hay 3 opciones para detectar desconexiones:

 

1. Si utiliza TsgcWebSocketClient, puede habilitarlo en la propiedad Options, CleanDisconnect := True (por defecto está desactivado). Si está habilitado, antes de que el cliente se desconecte envía un mensaje informando al servidor sobre la desconexión, de modo que el servidor recibirá este mensaje y se generará el evento OnDisconnect.

2. Puede habilitar el heartbeat en el lado del servidor, por ejemplo cada 60 segundos, de modo que intentará enviar un ping a todos los clientes conectados y, si algún cliente se desconecta, se llamará a OnDisconnect.

3. Puede habilitar TCPKeepAlive y/o establecer KeepAliveTimeout en las IOHandlerOptions del servidor. Esto permite que el propio servidor detecte un par que ha dejado de responder, por ejemplo porque el cliente ha fallado o la conexión de red se ha caído sin enviar un mensaje de cierre, y cierre la conexión, sin depender de que el cliente envíe nada.

 

Límite de Conexiones en Linux

 

Si desea aumentar el número de conexiones abiertas simultáneas, utilice el siguiente comando

 

ulimit -n 10000

 

El comando anterior establece el número máximo de descriptores de archivos abiertos en 10000