Compartir a través de


Impedir bloqueos del lado cliente

Hay dos maneras en que el cliente puede bloquearse: la conectividad de red puede provocar que se pierdan las solicitudes del servidor o que el propio servidor se bloquee. Con las opciones predeterminadas, RPC nunca agotará el tiempo de espera de una llamada y el subproceso de cliente esperará para siempre una respuesta.

Hay dos métodos para evitar esto: mantener vivo y agotar el tiempo de espera.

Mantenimiento activo de TCP

El cliente se puede configurar para hacer ping periódicamente al servidor para asegurarse de que el servidor está activo y en ejecución. Los pings son keep-alives de TCP para las secuencias de protocolo de ncacn_ip_tcp y ncacn_http , y como tal, son eficaces en el uso de cpu y el ancho de banda de red. Para habilitar keep alives en una llamada a procedimiento remoto determinada, use la función RpcMgmtSetComTimeout antes de iniciar la llamada. Esta función toma un identificador de enlace y un tiempo de espera como argumentos. Cada llamada a procedimiento remoto en este identificador de enlace después de RpcMgmtSetComTimeout usa el tiempo de espera proporcionado.

El parámetro Timeout de la función RpcMgmtSetComTimeout especifica cuánto tiempo espera el tiempo de ejecución de RPC antes de activar la conexión activa. El tiempo de espera es un valor entre 0 y 10, donde 0 es el tiempo de espera mínimo y 10 es un tiempo de espera infinito (sin tiempo de espera). El tiempo de espera no está en segundos; La traducción del valor de tiempo de espera proporcionado a la función RpcMgmtSetComTimeout en segundos se realiza en tiempo de ejecución de RPC y es específica de la implementación.

En la tabla siguiente se proporciona la traducción a segundos para Windows 2000 y Windows XP. Las versiones futuras de Windows pueden cambiar la asignación entre el parámetro Timeout y el valor de tiempo de espera en segundos:

Parámetro de tiempo de espera Tiempo de espera real en segundos
0 (RPC_C_BINDING_MIN_TIMEOUT) 120
1 240
2 360
3 480
4 600
5 (RPC_C_BINDING_DEFAULT_TIMEOUT) 720
6 840
7 960
8 1080
9 (RPC_C_BINDING_MAX_TIMEOUT) 1200
10 (RPC_C_BINDING_INFINITE_TIMEOUT) Tiempo de espera infinito

 

Una vez activada la conexión activa, el cliente envía un paquete keep alive cada segundo. Si no hay ninguna confirmación del servidor para tres o más mantenimientos activos, el cliente declara la conexión inactiva y produce un error en la llamada a procedimiento remoto. Si el servidor envía una respuesta dentro del tiempo de espera especificado, no se activarán las conexiones activas. Si el servidor responde para mantener la vida activa, pero no responde a la llamada a procedimiento remoto, el cliente continúa enviando keep alives. Una vez que el servidor responde a la llamada RPC, se desactivan las entidades de mantenimiento activo. En el caso de Windows 2000, mantener las conexiones activas solo se activan para llamadas RPC sincrónicas. Para Windows XP, también se activan las llamadas RPC asincrónicas.

Es tentador establecer mantener vivo en el valor más bajo para asegurarse de que la aplicación cliente responde a problemas de red de forma oportuna. Se debe tener en cuenta detenidamente dicha tentación y examinar si se garantiza un valor agresivo. Un servidor que pierde temporalmente la conectividad puede encontrarse inundado con mantener la vida de numerosos clientes una vez restaurada la conectividad. Además, las tareas de cálculo largas pueden tardar más de dos minutos, y el servidor puede encontrar que el servidor dedica más tiempo de CPU a responder con vida que realizar un trabajo útil. Por lo tanto, se debe usar keep alives con moderación. Si el cliente no puede tolerar que su subproceso esté vinculado durante largos períodos, se debe tener en cuenta RPC asincrónico.

Otras secuencias de protocolo pueden implementar diferentes mecanismos para detectar servidores que no responden, en función del transporte que se use. El transporte de ncalrpc no usa keep alives. Dado que todas las comunicaciones de ncalrpc son locales, si el servidor deja de responder mientras una llamada está en curso, el tiempo de ejecución de RPC en el cliente produce un error inmediatamente en la llamada.

Tiempos de espera de llamadas

El mantenimiento de TCP está bien si se pierde la conectividad de red o si el servidor se bloquea. Sin embargo, si los interbloqueos del servidor en modo de usuario, TCP mantiene activo se devuelven correctamente, pero la llamada nunca volverá. Para tratar este escenario, se agregó una nueva opción en tiempo de ejecución para Windows XP: RPC_C_OPT_CALL_TIMEOUT. Esta opción indica al tiempo de ejecución rpc que configure un temporizador cada vez que envía una solicitud al servidor. Si el temporizador expira, la llamada se cancela automáticamente y se completa con RPC_S_CALL_CANCELLED. Siempre que el servidor responda dentro del límite de tiempo especificado, el cliente no cancelará la llamada. Esto significa que una llamada multifragment puede tardar más que el período de tiempo de espera en completarse, ya que cada respuesta del servidor se recibe dentro del período de tiempo de espera, aunque el período de tiempo de espera de todas las respuestas para llegar fuera superior al período de tiempo de espera.

Además, cuando se cancela una llamada, el servidor no recibe una notificación de la cancelación. Por lo tanto, el servidor probablemente ejecutará la llamada en algún momento y el cliente simplemente omitirá la respuesta del servidor.

El problema más peligroso con los tiempos de espera de llamadas es establecer un breve tiempo de espera y reintentar la llamada en el mismo servidor. En el escenario siguiente se muestran los peligros de este enfoque:

Imagine un servidor que funciona cerca de la capacidad. Tiene una serie de clientes con tiempos de espera muy cortos, como cinco segundos. Una pérdida temporal de conectividad de red o congestión en un enrutador provoca un error en las respuestas del servidor durante unos segundos. En las redes Ethernet, esta situación puede deberse fácilmente a una ráfaga de actividad en un vínculo que el servidor comparte con otra máquina. El servidor no administra para enviar todas las respuestas antes del tiempo de espera de cinco segundos. Los clientes reciben sus llamadas canceladas y vuelven a intentarlo inmediatamente. El servidor no es consciente de que las llamadas son reintentos y las ejecuta también. Por lo tanto, en lugar de ejecutar su carga de trabajo normal de llamadas, ejecuta 30-50 % más llamadas, dependiendo del tiempo de espera de los clientes. Si esto supera su capacidad y el servidor no puede responder a todos los clientes en un plazo de cinco segundos, se envía otra ronda de llamadas al servidor. Los clientes mantienen la reemisión de las mismas llamadas y, dado que el servidor está sobrecargado procesando llamadas anteriores, no puede responder dentro del tiempo de espera. Una vez que responde, los clientes han agotado el tiempo de espera, han emitido una nueva llamada y descartan la respuesta. En el peor de los casos, el servidor no se recuperará hasta que se reinicie y, en función del patrón de acceso de cliente, es posible que no se recupere hasta que se detenga un número suficiente de clientes.

Nota

Los tiempos de espera de llamadas solo funcionan en las secuencias de protocolo ncacn_ip_tcp y ncacn_http .