Netty
netty学习笔记
预备
-
什么是Netty? 异步的、基于事件驱动的网络应用框架,用于快速开发高性能、高可靠的网络IO程序 主要针对TCP协议下,面向Clients端的高并发应用 本指是一个基于TCP的NIO框架,只是对原生的NIO做了一个封装。
-
应用场景 高性能RPC框架必不可少,例如Dubbo 游戏行业中,处理大并发
I/O模型
Java共支持3中网络编程模型I/O模式:BIO、NIO、AIO
-
BIO(同步阻塞) 服务器实现模式为一个连接一个线程
-
NIO(同步非阻塞) 一个线程处理多个请求,即客户端发送的连接请求都会注册到多路复用器上(selector),多路复用器轮询到连接有IO请求就进行处理,适合于连接数目多连接比较短的架构,例如聊天服务器弹幕系统等
-
AIO(异步非阻塞) AIO引入异步通道的概念,采用了Proactor模式,简化了程序的编写,有效的请求才启动线程,特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用
NIO
-
NIO相关的类都放在java.nio包及其子包下
-
NIO三大核心:Channel、Buffer、Selector
-
NIO是面向缓冲区或面向块编程的,数据读取到一个缓冲区,需要时可在缓冲区前后移动
-
三大组件的关系
graph Thread ---> Selector Selector ---> Channel1 Selector ---> Channel2 Selector ---> Channel3
Channel1 —> Buffer1 Channel2 —> Buffer2 Channel3 —> Buffer3
Buffer1 —> Client1 Buffer2 —> Client2 Buffer3 —> Client3
1. 每一个Channel都会对应一个Buffer
2. Selector对应一个线程,一个线程对应多个Channel(连接)
3. 该图反映了三个Channel注册到该Selector
4. 程序切换到哪个Channel是由事件(Event)决定的
5. Selector会根据不同的事件在各个Channel上切换
6. Buffer本质是一个数组
7. 数据的读取和写入都是要通过Buffer,通过flip方法切换
##### Buffer
本质是一个可以读写的数据块,可以理解成一个容器对象(包含了一个数组),该对象提供了一组方法可以轻松的使用内存块。缓冲区对象内置了一些机制,能够追踪和记录缓冲区的状态变化情况,JDK提供了除了boolean之外的其他七种基本类型的Buffer
```java
public static void main(String[] args) {
IntBuffer buffer = IntBuffer.allocate(3);
for (int i = 0; i < buffer.capacity(); i++) {
buffer.put(i);
}
// 读写转换(重要)
buffer.flip();
// 是否还存在值
while (buffer.hasRemaining()) {
// get方法内部存在一个游标
System.out.println(buffer.get());
}
}
- Buffer类(所有Buffer父类)定义了所有缓冲区都具有的四个属性
- Capacity:容量,创建时指定,不能改变
- Limit:缓冲区的当前终点,不能对超过该值的位置进行读写操作
- Position:游标,每次读写数据都会改变
- Mark:标记,很少主动修改
Channel
类似于流,但可以双向读写(实际上channel是Stream中的一个属性) Channel在Java中是一个接口,常用的实现类:FileChannel、ServerSocketChannel、SocketChannel等 使用transferFrom/transterTo方法实现文件的快速拷贝 提供了MappedByteBuffer支持直接在堆外内存中修改文件,而不用操作系统多拷贝一次