2.Netty入门第二章——NIO介绍

2017-07-20  本文已影响36人  NormanHu

1. 同步阻塞BIO

  1. serversocket负责绑定IP和Port,socket负责发起连接操作。连接成功后,通过输入/输出流进行同步阻塞式通信。
  2. 传统请求-应答模型,Acceptor线程每接受一个请求,创建一个线程处理请求并返回。

2. 伪异步IO

  1. 后来考虑到高性能/高并发场景,演进了用线程池/消息队列实现1个或多个线程处理N个客户端。但底层通信机制仍是同步阻塞IO,故称作“伪异步”。线程池中的线程数量和队列大小可控,因此不会导致资源耗尽和宕机。
  2. 弊端:JDK的API文档中,对于InputStream和OutputStream中的read(byte[] b)和write(byte[] b)操作,都是同步阻塞的,亦即一直阻塞直到发生如下事件:
  3. 有数据可读。
  4. 读到数据末尾。
  5. 发生空指针或IO异常。

如果大量连接上来,前端只有一个Acceptor线程接入请求,那么,之前的请求在线程池中的队列(阻塞队列实现)中排队,队列满,入队操作阻塞,新请求将被拒绝。破解这一难题,NIO入场。

3. NIO编程

官方New IO,更多人接受Non-block IO.与Socket和ServerSocket类似,NIO提供了SocketChannel和ServerSocketChannel套接字通道实现,且支持阻塞非阻塞模式。

3.1. 缓冲区Buffer

在NIO中,所有的数据操作都是面对缓冲区的,从缓冲区读,往缓冲区写。实现原理是数组

3.2. 通道Channel

通道与流的不同,在于通道是双向的,而流是单向的。通道可用于读、写、同时读写。同时支持阻塞和非阻塞模式。

3.3. 多路复用器Selector

多路选择器提供了选择已经就绪的任务的能力。Selector会不断轮询注册其上的Channel,如果某个Channel上有新的TCP连接、读、写事件,这个Channel就处于就绪状态,会被Selector轮询出来。JDK使用了epoll()代替了select()实现,没有最大连接句柄数1024/2048的限制,一般1GB内存支持100 000个连接。

4. AIO 编程

NIO2.0引入新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。是真正的异步非阻塞IO,对应unix的事件驱动IO(AIO),不需要Selector对其轮询即可实现异步读写。

5. 总结

5.1. 不选择原生NIO编程原因

  1. NIO类库和API非常负责,使用麻烦。
  2. 需具备其他技能做铺垫,如Java多线程编程,Reactor模式等。
  3. 可靠性不够,如客户端断连重连,网络闪断,半包读写,失败缓存等。
  4. JDK的NIO bug,如epoll bug,它会导致Selector空轮询,导致CPU使用率100%。

5.2. 为什么选择Netty

  1. API使用简单,开发门槛低。
  2. 功能强大,预置了多种编解码功能,支持主流协议。
  3. 定制能力强。
  4. 性能高。
  5. 成熟稳定,修复了已发现的所有NIO bug。
  6. 社区活跃,版本迭代周期短。
  7. 经过了大规模的商用考验。
上一篇下一篇

猜你喜欢

热点阅读