Como você minimiza o número de threads usados ​​em um aplicativo de servidor TCP?

StackOverflow https://stackoverflow.com/questions/32198

Pergunta

Estou procurando estratégias que as pessoas usam ao implementar aplicativos de servidor que atendem solicitações TCP (ou UDP) de clientes:padrões de design, técnicas de implementação, melhores práticas, etc.

Vamos supor, para efeitos desta questão, que as solicitações tenham vida relativamente longa (vários minutos) e que o tráfego seja sensível ao tempo, portanto, nenhum atraso é aceitável na resposta às mensagens.Além disso, atendemos solicitações de clientes e fazemos nossas próprias conexões com outros servidores.

Minha plataforma é .NET, mas como a tecnologia subjacente é a mesma, independentemente da plataforma, estou interessado em ver respostas para qualquer idioma.

Foi útil?

Solução

A abordagem moderna é usar o sistema operacional para multiplexar muitos soquetes de rede para você, liberando seu aplicativo para processar apenas conexões ativas com tráfego.

Sempre que você abre um soquete, ele é associado a um seletor.Você usa um único thread para pesquisar esse seletor.Sempre que os dados chegarem, o seletor indicará o soquete que está ativo, você transfere essa operação para um thread filho e continua a pesquisa.

Dessa forma, você só precisa de um thread para cada operação simultânea.Soquetes abertos, mas ociosos, não amarrarão um thread.

Outras dicas

Uma abordagem mais sofisticada seria usar portas de conclusão de E/S.(Windows) Com as portas de conclusão de IO que você deixa para o sistema operacional para gerenciar a pesquisa, o que permite que ela potencialmente use um nível muito alto de otimização com o suporte ao driver NIC.Basicamente, você tem uma fila de operações de rede gerenciada pelo sistema operacional e fornece uma função de retorno de chamada que é chamada quando a operação é concluída.Um pouco como DMA (disco rígido), mas para rede.

Len Holgate escreveu uma série excelente sobre portas de conclusão de IO há alguns anos no Codeproject:http://www.codeproject.com/KB/IP/jbsocketserver2.aspx

E eu encontrei um artigo sobre portas de conclusão de IO para .NET (ainda não li)http://www.codeproject.com/KB/cs/Managediocp.aspx

Eu também diria que é fácil usar portas de conclusão em comparação com tentar escrever uma alternativa escalonável.O problema é que eles só estão disponíveis no NT (2000, XP, Vista)

Se você estivesse usando C++ e Win32 diretamente, sugiro que você leia sobre portas sobrepostas de E/S e de conclusão de E/S.Eu tenho uma estrutura cliente/servidor C++, IOCP gratuita com código-fonte completo, consulte aqui para mais detalhes.

Como você está usando .Net, você deve usar os métodos de soquete assíncronos para não precisar de um thread para cada conexão;existem vários links desta postagem do meu blog que podem ser pontos de partida úteis: http://www.lenholgate.com/blog/2005/07/disappointing-net-sockets-article-in-msdn-magazine-this-month.html (alguns dos melhores links estão nos comentários da postagem original!)

Bom dia,

Eu começaria examinando a metáfora que você deseja usar para sua estrutura de threads.

Talvez "líder seguidor", onde um thread está escutando as solicitações recebidas e quando uma nova solicitação chega, ele faz o trabalho e o próximo thread no pool começa a ouvir as solicitações recebidas.

Ou pool de threads onde o mesmo thread está sempre ouvindo solicitações recebidas e depois passando as solicitações para o próximo thread disponível no pool de threads.

Talvez você queira visitar o Reator seção dos Componentes Ace para ter algumas idéias.

HTH.

Saúde, Rob

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top