前言
Netty如今是使用最广泛的网络通信框架,许多人对此有强烈的学习需求。但是Netty本身代码量大、概念众多,单纯看代码学习容易一头雾水,看了后面忘了前面。这个问题的破解之道,就是以自己的思考重新写一遍,这是掌握一个复杂设计的最好方法。本文会带着你从零开始设计一个极简版的Netty,为你演示如何从最原始的BIO进化到NIO,再一步步添加Netty的Reactor线程模型和任务处理的。本文的源代码放在Github上(mini-netty),有兴趣的读者可以自己取阅。
BIO版本
先看最原始的BIO。BIO的特点是阻塞式的,它的API使用简单,但是缺点也很明显:一个连接对应一个线程,如果连接数量过多,那么线程数量也会很多,而CPU核数有限,造成大量不必要的线程切换开销。代码示例如下:
/**
* 基于BIO的客户端
*/
public class BioClient {
public static void main(String[] args) throws IOException {
try (Socket socket = new Socket("127.0.0.1", 13)) {
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
try (Scanner sc = new Scanner(System.in)) {
while(true){
// 循环从系统输入获取消息并发送
System.out.print("type in your msg:");
String msg = sc.nextLine();
ps.println(msg);
ps.flush();
}
}
}
}
}
/**
* 基于BIO的服务端
*/
public class BioServer {
public static void main(String[] args) throws IOException{
try (ServerSocket ss = new ServerSocket(13)) {
while(true){
// 循环接收新的连接,并启动新的线程处理对应连接的IO消息
Socket socket = ss.accept();
new Thread(){
@Override
public void run() {
try{
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg;
while((msg = br.readLine())!=null){
System.out.println("receive msg:" + msg);
}
}catch (Exception e){
e.printStackTrace();
}
}
}.start();
}
}
}
}
NIO版本
由于BIO的上述缺点,Java在后来的版本中推出了NIO,以获得非阻塞、更加可扩展的IO。NIO三大核心:Selector、Buffer、Channel。其中又以Selector为首,它仅需一个主线程循环,便可以通过收集和处理事件的方式,管理成千上万个连接,整个过程不会阻塞。示例代码如下:
/**
* 基于NIO的客户端
*/
public class NioClient {
public static void main(String[] args) throws Exception{
// 启动16个socket分别发送消息
for (int i = 1; i <= 16; i++) {
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 13);
SocketChannel socketChannel = SocketChannel.open(inetSocketAddress);
socketChannel.configureBlocking(false);
String msg = "msg" + i;
ByteBuffer byteBuffer = ByteBuffer.wrap(msg.getBytes());
System.out.println("socket" + i + " send msg:" + msg);
socketChannel.write(byteBuffer);
socketChannel.close();
Thread.sleep(100);
}
}
}

本文通过逐步讲解,从最基本的BIO模型开始,过渡到NIO,然后引入Reactor线程模型,最后添加任务处理系统,构建了一个迷你版的Netty。展示了Netty如何解决BIO的线程消耗问题,以及如何利用NIO的非阻塞特性提高效率,最后通过任务系统优化了selector的超时时间选择,使得系统性能更优。
最低0.47元/天 解锁文章
1112

被折叠的 条评论
为什么被折叠?



