NIO: 全称Non-Block IO,也可以叫做New IO,非阻塞+同步的通信模式
原理: 客户端和服务端通过Channel通信,NIO可以在Channel进行读写操作,这些Channel都会被注册在Selector多路复用器上,Selector通过一个线程不断轮询这些Channel。找出已经准备就绪的Chnnal执行IO操作
补充知识
阻塞与非阻塞
阻塞和非阻塞,是指程序等待返回结果的状态。
阻塞: 在调用结果返回前,线程挂起
非阻塞: 如果不能立即得到结果,程序不会等待。非阻塞需要程序定时轮询查看处理结果
Channel,Selector,ByteBuffer,Socket
Channel(通道): 链接ByteBuf和Event的桥梁,连接网络输入和IO处理的桥梁,读写双向通道,可以输入数据也可以输出数据。通过Channle可判断当前的状态,还可以判断当前Channel支持的IO操作,使用ChannelPipeline处理Channel中的消息。可以理解为增强版的IO操作方式。
Channel包提供了
**Selector(选择器):**用于管理Channel组件,控制用哪些Channel读写,通过Selector可以通过一个单线程管理多个Channel甚至多个网络连接
演化模式
早期服务器是多线程设计,每个客户端来一个socket就开一个新的线程通讯,但是线程太多,CPU核心数有限。内存占用高,上下文切换陈本高,只适合链接少的场景
这时候考虑通过线程池改善线程过多的缺点,使得一个线程可以处理多个客户端的链接。但是一个线程只能处理一个socket,存在线程阻塞,线程阻塞过程中不能执行别的任务。阻塞模式,线程复用率不高,只适合短连接的场景
Selector设计配一个线程管理多个Channel,这些channel工作在非阻塞模式下提高线程复用率。适用连接数特别多,流量低的场景
Selector能监测到所有channel事件,调用selector的select()方法阻塞到channel发生读写事件,select方法就返回事件给线程来处理
**ByteBuffer(字节流):**暂时不进行学习,可以参阅文章Netty导学之NIO,Channel、Buffer、Selector详解,写的很好。
Socket(嵌套字)
一个数据包有应用程序产生,进入协议栈中进行报文头包装,然后又系统调用网卡驱动只会网卡硬件,把数据发送到对端主机。
大体流程如下:
应用程序比如浏览器、电子邮件、文件传输服务器等产生的数据,会通过传输层进行传输。二应用程序是不会和传输层直接联系,而是有一个能够链接应用层和传输层之间的套件,这个套件就是Socket。
Selector、线程、Channel、Buffer关系
Selector对应一个线程,一个线程对应多个Channel,Channel对应一个Buffer
程序切换Cahnnel需要有事件触发queryMerShopCpWechatSerList
Selector根据不同的事件在各个通道上切换
接着拓展
JavaApi 提供两套NIO,一套用于标准输入输出,一套基于网络
曾今用的InputSteam、OutputSteam、Reader、Writer等相关API进行的IO操作都是阻塞的
NIO支持面向缓存区,以数据块为单位处理,基于通道IO操作,实现更加高效的方式进行文件读写。核心为API为**Channel(通道)、Buffer(内存缓冲区)、Selector(选择器)。**Channel负责传输,Buffer负责存储。
主从Reactor多线程模型
Netty模型基于reactor主从多线程模型
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap server = new ServerBootstrap();
server.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
上面代码中的BossGroup和WorkGroup是Bootstrap构造方法中传入的两个对象,这两个group都是线程池
补充知识
Bootstrap
**Bootstrap:**当需要引导客户端或者一些无连接协议时,需要使用Bootstrap。负责创建管道给客户端,作为客户端,则需要使用connectAPI来链接远程服务端
未完待续,已经根据上面的内容,个人已经完成了Netty长链接的编写,有继续的深入学习再补充