Pergunta

Para se divertir, eu estive brincando ao redor com a escrita de um balanceador de carga em python e foram tentando descobrir a melhor maneira (correto?) Para testar se uma porta está disponível e o host remoto ainda está lá.

Eu estou achando que, uma vez conectado, torna-se difícil dizer quando o host remoto vai para baixo. Virei continuar vivo, mas não pode obtê-lo a reconhecer uma conexão abatido mais cedo do que um minuto (eu percebo polling mais frequentemente do que um minuto pode ser um exagero, mas vamos dizer que eu queria), mesmo depois de definir os vários TCP_KEEPALIVE opções para seu mais baixo.

Quando eu uso nonblocking soquetes, tenho notado que um recv () retornará um erro ( "recurso temporariamente indisponível") quando se lê a partir de uma tomada ao vivo, mas retorna "" durante a leitura de um morto (envio e recv de 0 bytes, que pode ser a causa?). Isso parece uma maneira estranha de teste para ele conectados, porém, e faz com que seja impossível dizer se o ligado morreu, mas após enviar alguns dados.

Além de ligar / desligar para cada cheque, há algo que eu posso fazer? Posso enviar manualmente um keepalive TCP, ou posso estabelecer uma conexão de nível inferior que vai me deixar testar a conectividade sem enviar dados reais do servidor remoto seria potencialmente processo?

Foi útil?

Solução

Eu recomendo não deixar o seu socket (single) teste conectado - fazer uma nova conexão cada vez que você precisa para pesquisa. Cada sistema disponibilidade do balanceador de carga / servidor que eu já vi usam este método, em vez de uma conexão persistente.

Se o servidor remoto não respondeu dentro de um período razoável de tempo (por exemplo, 10s) marcá-lo como "para baixo". Utilize timers e sinais, em vez de códigos de resposta de função para lidar com esse limite de tempo.

Outras dicas

"torna-se difícil dizer quando o host remoto vai para baixo"

Correto. Este é um recurso do TCP. O ponto inteiro de TCP é ter uma conexão permanente entre os portos. Teoricamente um aplicativo pode cair e voltar a ligar ao porto através de TCP (as bibliotecas de soquete não fornecem muito apoio para isso, mas é parte do protocolo TCP).

ping foi inventado para o efeito

Além disso, você pode ser capaz de enviar pacotes TCP malformados para o seu destino. Por exemplo, nos cabeçalhos TCP existe uma bandeira para acknowleging final de transmissão, a sua mensagem a FIN. Se você enviar uma mensagem com ACK e FIN o host remoto deve queixar-se com um pacote de retorno e você será capaz de avaliar o tempo de ida e volta.

É teoricamente possível spam um pacote keep-alive. Mas, para configurá-lo para intervalos muito baixos, pode ser necessário escavar em soquetes brutos. Além disso, o anfitrião pode ignorá-lo se a sua vinda em demasiado rápido.

A melhor maneira de verificar se um host está vivo em uma conexão TCP é enviar dados, e esperar por um pacote ACK. Se o pacote ACK chega, a função SEND retornará diferente de zero.

Você pode usar festança de arquivos pseudo-dispositivo para TCP / UDP ligação com uma porta específica de I / O, por exemplo:

printf "" > /dev/tcp/example.com/80 && echo Works

Isso abriria a conexão, mas não vai enviar qualquer coisa. Você pode testá-lo:

nc -vl 1234 &
printf "" > /dev/tcp/localhost/1234

Para simples cron uso de monitoramento com comando acima ou usando watch:

watch bash -c 'echo > /dev/tcp/localhost/1234 && echo Works || echo FAIL'

No entanto, é recomendado para ferramentas específicas de uso que são projetados para que, como Monit, Nagios, etc.

Monit

Aqui está um exemplo regra usando Monit (monit):

# Verify host.
check host example with address example.com
  if failed
    port 80
    protocol http
  then alert
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top