Resumo: Compreensão da BIO e do NIO
Recentemente, provavelmente olhei o código-fonte do ZooKeeper e do Mina e descobri que ambos são implementados em Java NIO, então é necessário entender o que é NIO. A seguir, meu próprio resumo baseado em informações online; para economizar tempo, desenhei o diagrama casualmente, desde que conseguisse alcançar o significado.
Introdução:
BIO: Bloqueio síncrono de IO, o modo de implementação do servidor é conectar uma thread por vez, ou seja, quando o cliente tem uma solicitação de conexão, o servidor precisa iniciar uma thread para processamento; se essa conexão não fizer nada, isso causará sobrecarga desnecessária da thread, claro, isso pode ser melhorado através do mecanismo de pool de threads.
NIO: E/s síncrona não bloqueante, o modo de implementação do servidor é uma requisição por thread, ou seja, a solicitação de conexão enviada pelo cliente será registrada no multiplexador, e o multiplexador iniciará uma thread para processamento quando a conexão tiver uma requisição de I/O.
AIO (NIO.2): E/S assíncrona não bloqueante, o modo de implementação do servidor é efetivamente solicitar uma thread, e as requisições de I/O do cliente são completadas primeiro pelo sistema operacional e então notificam a aplicação do servidor para iniciar a thread para processamento.
BIO
O bloqueio síncrono de IO, acredito que todos que aprenderam programação de rede do sistema operacional ou qualquer linguagem de programação de rede estejam familiarizados; no loop while, o servidor chamará o método de aceitação para esperar a solicitação de conexão do cliente receptor; uma vez recebida uma solicitação, um soquete de comunicação pode ser estabelecido nesse soquete para operações de leitura e escrita; neste momento, ele não pode mais receber outras solicitações de conexão do cliente, só pode esperar a execução da operação com o cliente conectado atualmente.
Se a BIO quiser processar múltiplas requisições de cliente ao mesmo tempo, ela deve usar multithreading, ou seja, toda vez que aceitar blocos, espere por uma solicitação de cliente, uma solicitação de conexão recebida, um soquete de comunicação é estabelecido e uma nova thread é aberta para processar a requisição de leitura e escrita de dados desse soquete, e então imediatamente continuar aceitando e aguardando outras solicitações de conexão do cliente, ou seja, uma thread é criada para cada requisição de conexão cliente a ser processada individualmente, o esquema provavelmente é o seguinte:
C:/Users/kevin/AppData/Local/YNote/data/kevinsir2003@163.com/8107c3f773ad4d2aa1a5a476e650ef84/094528_zqyy.jpeg
Embora o servidor tenha alta concorrência atualmente, ou seja, ele possa lidar com múltiplas solicitações de clientes ao mesmo tempo, isso traz um problema: à medida que o número de threads abertas aumenta, consome muitos recursos de memória, fazendo o servidor desacelerar ou até mesmo travar, e o NIO pode resolver esse problema até certo ponto.
NIO
A chave para uma IO síncrona não bloqueante é adotar uma ideia orientada por eventos para implementar um multiplexador.
A maior diferença entre NIO e BIO é que você só precisa abrir uma thread para lidar com eventos de IO de múltiplos clientes.
É um multiplexador que pode ouvir eventos de IO de múltiplos clientes:
R. Se o servidor ouvir a solicitação de conexão do cliente, ele estabelecerá um socket de comunicação para ela (canal em Java) e depois retornará para continuar ouvindo.
B. Se o servidor escuta os dados enviados pelo cliente que criou um soquete de comunicação, ele chamará a interface correspondente para processar os dados recebidos, e se houver múltiplos clientes ao mesmo tempo, os dados também podem ser processados em sequência.
C. Ouça as solicitações de conexão de múltiplos clientes e receba pedidos de dados, e também ouça quando você tem dados para enviar.
C:/Users/kevin/AppData/Local/YNote/data/kevinsir2003@163.com/41709898aa0a4f8a830d7c348ed05fbb/094528_of9c.jpeg
Resumindo, em uma thread, você pode chamar a interface de multiplexação (select em Java) para bloquear e ouvir requisições de IO de múltiplos clientes ao mesmo tempo, e uma vez recebida uma requisição de IO, a função correspondente será chamada para processá-la.
Cenários de aplicação respectivos
A essa altura, você pode ter notado que, uma vez que uma solicitação chega (seja várias ao mesmo tempo ou apenas uma), a função correspondente de processamento de IO será chamada para lidar com ela, então:
(1) O NIO é adequado para lidar com cenários com um grande número de conexões, mas as conexões são relativamente curtas (operação leve), como Jetty, Mina, ZooKeeper, etc., todas implementadas com base no nio java.
(2) O método BIO é adequado para cenários onde o número de conexões é relativamente pequeno e fixo, o que exige altos recursos do servidor e é limitado a aplicações.
|