Este conteúdo foi discutido muitas vezes em cnblogs. Li algumas informações nos últimos dois dias e vi alguns indicadores simples de desempenho e discuti isso com todos.
Soquete + Threads/ThreadPool
Desempenho aproximado: menos de 1.500 conexões
Implementação: Aceitar um soquete e deixá-lo para um thread gerenciar. É relativamente estúpido, mas também é mais eficaz por ser um método síncrono, é muito conveniente de controlar. O mais avançado é entregá-lo a um pool de threads para gerenciamento. O pool de threads é hospedado automaticamente pelo sistema, economizando tempo de sobrecarga de threads. Para pequenos projetos gerais, isso é completamente suficiente e o desenvolvimento é simples. Mas esteja ciente de que se vários Sockets ocuparem threads no pool de threads por um longo tempo e houver muitas outras conexões, é fácil receber um aviso informando que você não tem threads suficientes para usar. Haha, é uma boa ideia deixar o Socket trabalhar menos e levar menos tempo. Mudar para uma CPU mais rápida é uma boa maneira. Além disso, se houver alguns componentes melhores do pool de threads de terceiros, você também poderá optar por usá-los, como SmartThreadPool.
Soquete + Selecionar
Desempenho aproximado: O desempenho diminui após mais de 1.500 conexões.
Implementação: Select é um modelo muito usado. É para pesquisar um ou mais Sockets na função de bloqueio e colocar o Socket para ser processado em um IList. Quando a pesquisa Select for concluída, nós mesmos processaremos o Socket neste IList. Para uso específico, consulte o MSDN. A eficiência do Select não pode ser considerada alta, pois quando há muitos Sockets a serem processados na fila, processar os últimos Sockets equivale a percorrer todos os Sockets anteriores, o que é muito antieconômico.
Soquete+Assíncrono
Desempenho aproximado: cerca de 7.500 conexões de clientes
Implementação: BeginXXXX, EndXXXX, todos nós estamos familiarizados com isso. Em última análise, o Socket assíncrono ainda usa a tecnologia de pool de threads, usando o pool de threads para lidar com E/S assíncrona. Isso levanta outra questão: qual método de implementação é usado para o pool de threads do .NET? Já vi alguém dizer antes que o pool de threads do .NET é implementado usando portas de conclusão. Não sei se isso está correto. a partir das informações que encontrei (espero que um amigo possa me dizer isso). O soquete assíncrono é muito mais complicado do que o fluxo de processamento de programas síncronos e o controle das funções de retorno de chamada assíncronas não é tão intuitivo quanto o método síncrono. Mas uma coisa que acho que deve ser observada é que a função de retorno de chamada deve ser usada levemente e não deve lidar com muitas transações. O processamento dos dados transferidos deve ser deixado para outros threads para processamento.
IOCP (porta de conclusão)
Desempenho aproximado: cerca de 20.000 a 50.000 conexões de clientes
. Implementação: Existem alguns pseudo-IOCPs no .NET. Não vi nenhum exemplo de SOCKET aberto implementado usando esses pseudo-IOCPs. As 20.000 a 50.000 conexões de clientes de que estou falando referem-se à situação de desenvolvimento em C++. Nesse caso, as tecnologias básicas que precisam ser usadas incluem pools de memória, algoritmos de consulta, etc.
Não há informações para verificar o número máximo de conexões que o pseudo-IOCP pode atingir. Se alguém souber, pode discutir. Além disso, muitos dos dados mencionados acima foram extraídos de algumas informações que eu mesmo não tentei, apenas estou trazendo para discussão com todos. Acho que um programa de servidor de alto desempenho pode exigir tecnologia que não seja apenas qual modelo usar, mas também muitos detalhes que precisam ser prestados atenção, como processamento de memória, qual algoritmo usar, etc. apenas em termos de custo de software. Definitivamente haverá investimento em hardware.