TCPKeepAlive y KeepAliveTimeout para servidores IOCP y EPOLL | eSeGeCe Blog

TCPKeepAlive y KeepAliveTimeout para servidores IOCP y EPOLL

· Componentes
sgcWebSockets TCPKeepAlive y KeepAliveTimeout para IOCP y EPOLL

Los motores de servidor IOCP (Windows) y EPOLL (Linux) de sgcWebSockets gestionan miles de conexiones con un pequeño grupo de hilos en lugar de un hilo por conexión, lo que los convierte en la opción adecuada para servidores bajo alta carga concurrente. Sin embargo, hasta ahora no tenían forma de detectar un interlocutor que se queda en silencio sin despedirse. Dos nuevas opciones, TCPKeepAlive y KeepAliveTimeout, cierran esa brecha.

Un interlocutor silencioso nunca genera un evento

IOCP y EPOLL están orientados a eventos: el motor permanece inactivo hasta que el sistema operativo le indica que un socket tiene datos, se ha cerrado o ha fallado. Esto funciona bien hasta que un interlocutor desaparece sin enviar un FIN o RST limpio, por ejemplo un cliente que falla, un NAT o firewall que descarta una asignación inactiva, o una ruta que cambia silenciosamente. Ningún evento llega jamás para ese socket, por lo que la conexión permanece ESTABLISHED en el servidor indefinidamente.

El clásico IOHandler de un hilo por conexión no tiene este problema, porque cada conexión se bloquea en una lectura con tiempo límite, de modo que una conexión silenciosa se detecta y se libera la próxima vez que esa lectura expira. IOCP y EPOLL no tenían un mecanismo equivalente, que es precisamente lo que añaden estas dos nuevas opciones.

TCPKeepAlive: deje que el sistema operativo vigile

Al activar TCPKeepAlive, el propio sistema operativo comienza a sondear una conexión en cuanto ha estado inactiva durante Time segundos, repitiendo cada Interval segundos hasta que el interlocutor responde o la conexión se descarta. Está desactivado de forma predeterminada; los valores siguientes coinciden con los valores por defecto al activarlo.

Server.IOHandlerOptions.IOHandlerType := iohEPOLL;
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Enabled  := True;
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Time     := 60;  // seconds idle before probing
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Interval := 10;  // seconds between probes

En un servidor Windows, las mismas tres propiedades se encuentran bajo IOHandlerOptions.IOCP.TCPKeepAlive.

KeepAliveTimeout: un tiempo límite de inactividad a nivel de aplicación

KeepAliveTimeout adopta un enfoque diferente y más directo: cierra cualquier conexión que haya permanecido inactiva más tiempo del número de segundos indicado, independientemente de lo que decidan los sondeos keepalive del sistema operativo. Es lo más parecido a cómo el IOHandler de un hilo por conexión ya libera una conexión silenciosa, está desactivado de forma predeterminada (un valor de 0), y solo afecta a las conexiones realmente inactivas, nunca interrumpe una solicitud que se está leyendo o una respuesta que se está escribiendo.

Server.IOHandlerOptions.EPOLL.KeepAliveTimeout := 120; // seconds

// Windows
Server.IOHandlerOptions.IOCP.KeepAliveTimeout := 120;

Configúrelo con un margen cómodo por encima de su solicitud o respuesta más lenta esperada, por ejemplo 120 segundos para un servidor HTTP o WebSocket típico, de modo que las conexiones realmente muertas se eliminen rápidamente sin tocar nunca una que simplemente sea lenta.

Una tercera forma de detectar una desconexión

sgcWebSockets ya ofrecía dos formas de detectar que un interlocutor ha desaparecido: activar CleanDisconnect en TsgcWebSocketClient, para que un cliente bien comportado avise al servidor antes de desconectarse, o ejecutar un heartbeat del lado del servidor que haga ping a cada cliente en un intervalo. Ambas dependen de la cooperación, del cliente en el primer caso, de su propio ciclo ping/pong en el segundo. TCPKeepAlive y KeepAliveTimeout son la primera opción que no necesita nada de eso: el servidor detecta una conexión muerta completamente por sí solo.

Disponibilidad

Ambas opciones ya están disponibles en sgcWebSockets para Delphi y C++ Builder 7 a 13, bajo IOHandlerOptions.EPOLL e IOHandlerOptions.IOCP, junto a las opciones existentes EPOLLThreads, IOCPThreads y WorkOpThreads. Están desactivadas de forma predeterminada, por lo que nada cambia en los servidores existentes a menos que las active.

Descargue la versión de prueba y consulte la referencia completa de IOCP y EPOLL en la página del producto sgcWebSockets.

¿Preguntas o comentarios? Póngase en contacto, recibirá respuesta de las personas que escribieron el código.