Netty系列(一)I/O

Netty系列(一)I/O

1. 4种I/O编程
1.1传统的BIO编程

​ 服务器端提供绑定的IP地址和端口号,客户端向该地址发送连接请求,如果成功则通过三次握手建立连接,连接成功就可以通过Socket进行网络通信。

​ 从下面BIO通信模型图可以看出来,服务器端存在一个Acceptor的线程负责监听客户端发送来的连接请求,一旦Acceptor线程收到一对一的创建新线程去处理,处理完之后该线程再由输出流返回给客户端,然后线程销毁。
在这里插入图片描述
​ 如果理解了它的通信原理就不难发现,一个请求对应服务器端的一个线程,如果并发访问量巨大的话则会创建无数个线程,那么到时候会发生线程堆栈溢出等问题,最终导致进程宕机。

1.2伪异步I/O编程

​ 传统BIO编程方式我们称之为一请求一应答模式,伪异步I/O是一种优化和改进。它可以通过一个线程池来处理多个客户端的请求接入。通过线程池可以灵活调配线程资源,设置线程的最大值,防止高并发接入导致线程耗尽。
在这里插入图片描述

​ 当客户端发来请求的时候,就将客户端的Socket封装成Task(实现Runnable类),然后放到Thread Pool处理。线程池可以设置消息队列大小还有最大线程数,所以当高并发访问的时候,不会导致资源的耗尽。

This method blocks until input data is available,end of file is deteccted,or an exception is thrown.

​ 这是Java输入流源码中的一段文字,当对输入流进行读取的时候会一直阻塞除非有数据可读、可用数据读取完毕、

空指针或IO异常才会不处于阻塞状态。当调用OutputStream的write方法写输出流的时候会被阻塞,直到所有要发送的字节全部写入完毕或者发生异常。这就有一个问题,当网络状态不好的时候线程将会被长时间阻塞,伪异步IO没有真正的从根源上解决同步IO导致的阻塞问题。

1.3NIO编程

​ NIO主要有三大核心部分:Channel,Buffer, Selector。传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。和传统IO不同的是,NIO面向块,传统IO面向的是流。

​ NIO的实现主要依靠Channel、Buffer、Selector,一个Selector可以同时轮询多个Channel,而且Selector没有最大连接句柄的限制,这也就是说只需要一个线程负责Selector的轮询,就可以接入成千上万个客户端。

​ Channel主要是负责网络数据的读取和写入,其中通道是双向的!以前流只是在一个方向上移动,不能实现全双工的模式。

​ Buffer是缓冲区,所有的数据都是用缓冲取处理的,直接读数据到缓冲区,直接将数据写入缓冲区。何时何地访问NIO数据都是通过缓冲区来完成的。缓冲区类型有很多,但是最常用的是ByteBuffer字节缓冲区。

1.4AIO编程

​ 事件驱动IO(AIO)。不需要通过多路复用器(Selector)对注册的通道进行轮询操作就可以实现异步读写,简化了NIO的编程模型。

2.选择Netty的理由

​ 使用JDK的NIO库直接开发的话,需要熟练掌握一些类库和API,然鹅这些API非常的繁杂使用也很麻烦,此外还需要开发人员熟悉多线程和网路编程等等,以及存在一些JDK NIO的BUG等等。

​ 相比较而言,Netty开发门槛低、功能强大,可以对通信框架灵活扩展,性能高。

发布了58 篇原创文章 · 获赞 5 · 访问量 6296

猜你喜欢

转载自blog.csdn.net/weixin_40992982/article/details/101349835