Mantendo conexões TCP ativas para rastrear quais clientes estão on-line

1

Estou desenvolvendo um aplicativo em que um servidor precisa ficar em contato com lotes de dispositivos IoT simples. Quase nenhuma troca de informações é necessária entre o servidor e cada dispositivo, mas os dispositivos precisam ficar on-line e acessíveis pelo servidor 24 horas. Em algum momento (o que acontece muito raramente), o servidor precisa ser capaz de entrar em contato com um dos dispositivos e trocar algumas mensagens: é crucial, no entanto, que esses dispositivos sejam alcançados em questão de um tempo muito curto. / p>

Isso significa que eu preciso que esses dispositivos clientes estejam de alguma forma conectados continuamente. Agora, eu me pergunto: é possível simplesmente conectar esses dispositivos via TCP e manter essas conexões ativas para estar sempre pronto para trocar mensagens?

Eu tentei ler e sempre leio a mesma resposta: depende da sua implementação, pois é muito provável que a troca e o processamento de mensagens sejam o gargalo em vez de manter essas conexões TCP ativas . Agora, este não é realmente o meu caso, já que eu só preciso trocar uma quantidade muito limitada de informações a cada lotes de tempo.

Então é razoável manter apenas esses clientes conectados? Ou devo conceber um método mais eficiente? Por exemplo, quanta largura de banda é necessária para manter uma conexão TCP viva sem qualquer troca de dados? E isso requer uma quantidade significativa de memória ou CPU?

Eu implementei um programa C ++ simples que envia o UDP para o meu servidor a cada alguns segundos: conforme meus benchmarks, isso pode escalar vários milhões de dispositivos on-line sem nenhum problema, mesmo em um servidor razoavelmente limitado. O TCP terá um desempenho pior que esse?

    
por Matteo Monti 14.08.2015 / 18:25

2 respostas

3

Quanto à minha compreensão do TCP, afirmar " Manter as conexões TCP ativas " é enganoso, pois não há nenhum mecanismo específico do protocolo TCP lidando com o tempo limite, quando referido para conexões ESTABELECIDAS . Quero dizer: uma vez estabelecidos, eles podem durar para sempre, até que um RESET, um FIN ou um timeout no recebimento de um ACK (... após alguma transmissão para ser reconhecida, neste último caso) aconteça.

Quanto à minha experiência, 100% dos problemas " subitamente quebrados devido ao tempo limite inativo " dependem de algum roteador intermediário / firewall, ao longo do caminho de roteamento entre os dois hosts de comunicação. Quero dizer: como o firewall é tipicamente um firewall "statefull", ele monitora as conexões que ele está protegendo / gerenciando. Como tal, toda conexão que precisa rastrear significa algum grau de recursos do sistema (do firewall, quero dizer) para ser consumido. Além disso, o firewall sabe perfeitamente quais das conexões gerenciadas estão "funcionando" e quais delas, viceversa, estão "ociosas", devido à própria natureza do próprio firewall (é um firewall stateful !). Como tal, muitos (todos?) Das implementações de firewall têm um tempo limite definido e se as conexões gerenciadas estiverem ociosas para tal valor de tempo limite, o firewall envia uma redefinição para as duas extremidades (... da conexão TCP) e libera seus próprios recursos.

Com base na sua pergunta, aposto que a conexão TCP será aberta pelo seu dispositivo IoT (agindo como um cliente) versus seu servidor de controle (o servidor TCP). Portanto ... LOTES , se não ALL , do roteador doméstico ADSL que ativará o tráfego do dispositivo IoT, certamente funcionará conforme descrito.

Isso, pelo menos, com base na minha própria experiência.

Mas como eu não sou Jon Postel , por favor não me culpe se eu estiver errado :-)

Como uma nota lateral: você escreveu " ... MUITOS dispositivos IoT simples ... ". Por favor, tenha em mente que há um limite muito rígido no número de conexões TCP simultâneas que você pode manipular com seu servidor de um único servidor como .... A "porta" TCP é um valor de 16 bits. Portanto, para cada endereço IP, você não pode exceder (por design intrínseco de TCP) conexões de 64K. Como esses problemas podem ser resolvidos, está fora do escopo, no contexto desta questão.

Por fim, deixe-me acrescentar que realmente vejo um problema no ao implementar uma espécie de protocolo de heartbeat entre o dispositivo IoT e o servidor / aplicativo de gerenciamento. Ele pode ser implementado para ser muito "amigável à rede", sem impacto em termos de largura de banda e com lotes de vantagens, em termos de capacidade de gerenciamento / controle.

    
por 14.08.2015 / 19:14
2

Sua ideia está bem; na verdade, dispositivos móveis modernos usam exatamente a mesma abordagem para suas notificações, eles mantêm uma conexão permanente com o servidor do desenvolvedor do SO e esse servidor envia notificações para essa conexão (desenvolvedores de aplicativos de terceiros enviam notificações para o desenvolvedor do SO, que as retransmite ao dispositivo móvel apropriado).

Um método alternativo pode ser usado se os seus dispositivos tiverem um IP publicamente roteável e puderem ouvir em um soquete; Nesse caso, os dispositivos notificarão o seu servidor cada vez que o IP for alterado, mas sempre que o servidor precisar entregar alguns dados ao dispositivo, o servidor se conectará ao soquete do dispositivo e enviará os dados. Dessa forma, o servidor não precisará manipular nenhuma carga além de atualizar o endereço IP de cada dispositivo em seu banco de dados e ocasionalmente se conectar a um dispositivo e enviar dados.

Sobre TCP vs UDP, acredito que o TCP é melhor para garantir a acessibilidade de um dispositivo - com o TCP, desde que a conexão esteja aberta, você tem alguma garantia de que o dispositivo ainda está lá (caso contrário, a conexão teria expirado). Com o UDP, você só está jogando pacotes no ar sem saber se eles chegaram ao destino (a menos que você implemente seu próprio sistema de retransmissão e gerenciamento de conexões, mas por que reinventar a roda quando você já tem um sólido e implementação popular chamada TCP?). Também é preciso pensar em firewalls e NAT, com o TCP uma vez estabelecida a conexão, você tem certeza de que o que quer que seja enviado para o destino, enquanto com UDP você não pode ter tanta certeza e ter que fazer furos com vários graus de sucesso .

    
por 14.08.2015 / 19:09