Compartilhar via


Impedindo travamentos do lado do cliente

Há duas maneiras pelas quais seu cliente pode travar: a conectividade de rede pode fazer com que as solicitações de servidor se percam ou o próprio servidor possa falhar. Com as opções padrão, o RPC nunca atingiu o tempo limite de uma chamada e o thread do cliente aguardará para sempre uma resposta.

Há dois métodos para evitar isso: manter vivos e tempos limite.

TCP Keep Alives

O cliente pode ser configurado para executar ping periodicamente no servidor para garantir que o servidor esteja ativo e em execução. Os pings são keep alives TCP para as sequências de protocolo ncacn_ip_tcp e ncacn_http e, como tal, são eficientes na utilização da CPU e na largura de banda da rede. Para habilitar keep alives em uma determinada chamada de procedimento remoto, use a função RpcMgmtSetComTimeout antes que a chamada seja iniciada. Essa função usa um identificador de associação e um tempo limite como argumentos. Cada chamada de procedimento remoto nesse identificador de associação após RpcMgmtSetComTimeout usa o tempo limite fornecido.

O parâmetro Timeout para a função RpcMgmtSetComTimeout especifica quanto tempo o tempo de execução do RPC aguarda antes de ativar keep alives. O tempo limite é um valor entre 0 e 10, em que 0 é o tempo limite mínimo e 10 é tempo limite infinito (sem tempo limite). O tempo limite em si não é em segundos; a tradução do valor de tempo limite fornecido para a função RpcMgmtSetComTimeout em segundos é feita pelo tempo de execução RPC e é específica da implementação.

A tabela a seguir fornece a tradução para segundos para Windows 2000 e Windows XP. Versões futuras do Windows podem alterar o mapeamento entre o parâmetro Timeout e o valor de tempo limite em segundos:

Parâmetro de tempo limite Tempo limite real em 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) Tempo limite infinito

 

Depois que o keep alive é ativado, o cliente envia um pacote keep alive a cada segundo. Se não houver nenhuma confirmação do servidor para três ou mais keep alives, o cliente declarará a conexão inativa e falhará na chamada de procedimento remoto. Se o servidor enviar uma resposta dentro do tempo limite especificado, keep alives não será ativado. Se o servidor responder a keep alives, mas não responder à chamada de procedimento remoto, o cliente continuará enviando keep alives. Depois que o servidor responde à chamada RPC, os keep alives são desativados. Para o Windows 2000, keep alives são ativados somente para chamadas RPC síncronas. Para o Windows XP, keep alives também são ativados para chamadas RPC assíncronas.

É tentador definir keep alives como o valor mais baixo para garantir que o aplicativo cliente responda a problemas de rede em tempo hábil. Deve-se considerar cuidadosamente essa tentação, e o escrutínio aplicado a se um valor agressivo é justificado. Um servidor que perde temporariamente a conectividade pode ser inundado com keep alives de vários clientes depois que a conectividade é restaurada. Além disso, tarefas computacionais longas podem levar mais de dois minutos, e o servidor pode gastar mais tempo de CPU respondendo keep alives do que executando um trabalho útil. Portanto, keep alives deve ser usado com moderação. Se o cliente não puder tolerar que seu thread seja vinculado por longos períodos, o RPC assíncrono deverá ser considerado.

Outras sequências de protocolo podem implementar mecanismos diferentes para detectar servidores sem resposta, dependendo de qual transporte é usado. O transporte ncalrpc não usa keep alives. Como todas as comunicações no ncalrpc são locais, se o servidor ficar sem resposta enquanto uma chamada estiver em andamento, o tempo de execução do RPC no cliente falhará imediatamente na chamada.

Tempos limite de chamada

Os keep alives do TCP serão adequados se a conectividade de rede for perdida ou se o servidor falhar. No entanto, se o servidor estiver em deadlock no modo de usuário, o TCP manterá o retorno ativo com êxito, mas a chamada nunca retornará. Para lidar com esse cenário, uma nova opção de tempo de execução foi adicionada para o Windows XP: RPC_C_OPT_CALL_TIMEOUT. Essa opção instrui o tempo de execução do RPC a configurar um temporizador sempre que ele envia uma solicitação para o servidor. Se o temporizador expirar, a chamada será cancelada automaticamente e concluída com RPC_S_CALL_CANCELLED. Desde que o servidor responda dentro do limite de tempo especificado, o cliente não cancelará a chamada. Isso significa que uma chamada multifragment pode levar mais do que o período de tempo limite para ser concluída, pois cada resposta do servidor é recebida dentro do período de tempo limite, mesmo que o período de tempo para todas as respostas cheguem foi maior do que o período de tempo limite.

Além disso, quando uma chamada é cancelada, o servidor não é notificado sobre o cancelamento. Portanto, o servidor provavelmente executará a chamada em algum momento e o cliente simplesmente ignorará a resposta do servidor.

A armadilha mais perigosa com tempos limite de chamada é estabelecer um curto tempo limite e repetir a chamada no mesmo servidor. O cenário a seguir ilustra os perigos dessa abordagem:

Imagine um servidor que opera perto da capacidade. Ele tem vários clientes com tempos limite muito curtos, como cinco segundos. Uma perda temporária de conectividade de rede ou congestionamento em um roteador causa um lapso nas respostas do servidor por alguns segundos. Em redes Ethernet, essa situação pode ser facilmente causada por uma intermitência de atividade em um link que o servidor compartilha com outro computador. O servidor não consegue enviar todas as respostas antes do tempo limite de cinco segundos. Os clientes recebem suas chamadas canceladas e repitam imediatamente. O servidor não está ciente de que as chamadas são novas tentativas e as executa também. Assim, em vez de executar sua carga de trabalho normal de chamadas, ele executa de 30 a 50% mais chamadas, dependendo de quantos clientes atingiu o tempo limite. Se isso exceder sua capacidade e o servidor não puder responder a todos os clientes dentro de cinco segundos, outra rodada de chamadas será enviada ao servidor. Os clientes continuam reutilizando as mesmas chamadas e, como o servidor está sobrecarregado processando chamadas anteriores, não é possível responder dentro do tempo limite. Depois de responder, os clientes atingiram o tempo limite, emitiram uma nova chamada e descartaram a resposta. Na pior das hipóteses, o servidor não será recuperado até que a reinicialização e, dependendo do padrão de acesso do cliente, não se recupere até que um número suficiente de clientes seja interrompido.

Observação

Os tempos limite de chamada funcionam apenas nas sequências de protocolo ncacn_ip_tcp e ncacn_http .