本文是结合JavaGuide的总结
Netty总结
IO基本知识
IO读写基本原理
read
系统调用和write
系统调用都只是内核缓冲区和进程缓冲区的操作。
read系统调用将内核缓冲区的数据复制到进程缓冲区
write系统调用将进程缓冲区数据复制到内核缓冲区。
至于具体的内核缓冲区到磁盘的过程则由操作系统内核进行
。
由此可知,用户程序的IO操作如Socket,文件IO都是上层应用开发,他们的输入输出处理,在编程流程上都是一致的。
缓冲区的作用
减少频繁的与物理设备的数据交换。在数据写入到磁盘的过程中会产生中断,系统中断的时候,系统需要保持相应的进程信息,而中断结束后需要进行恢复。缓冲区就减少了这种中断对于系统的开销。
四大IO模型
- 阻塞IO:指用户空间程序的状态,内核IO操作彻底完成了后,才返回到用户空间执行用户操作。Java中的默认创建的socket就是阻塞IO
- 同步IO和异步IO:
同步IO是指:用户空间程序的线程是主动发起IO的一方,内核空间是被动接受的一方。
异步IO是指:内核空间时发起IO的一方而用户空间程序是接受的一方。
同步阻塞IO(Blocking IO)
:用户程序需要等待内核IO操作完成才能继续执行。
同步非阻塞IO(Non-bolcking IO):
用户程序并不需要等待内核IO操作完成就可以执行下一步操作。在这个过程中内核会返回给用户空间一个状态值。
不是JAVA中的NIO(New IO)
IO多路复用
:又称为异步阻塞IO,就是Reactor反应器模式,Java中的Selector选择器和Linux中的epoll都是这种模型。
异步IO(Asynchronous IO)
:用户进程的线程向内核空间注册了各种IO事件回调函数,由内核去主动调用。
如何通过合理的配置支持百万级并发连接
在开发高并发的系统时,需要解除Linux的文件句柄限制。Linux默认的是1024.也就是说一个进程可以接受1024个socket连接。
文件句柄,也叫文件描述符。
文件句柄是内核为了高效管理已经被打开的文件所常创建的索引。
Linux通过ulimite -n 文件句柄数量 来修改文件句柄数
。但是这种方式只是在用户登录时有效。
如果想永久修改,需要修改/etc/rc.local
开机启动文件,添加:ulimite -SHn
数量
也可以直接通过修etc/secuity/limites.conf’
加入如下内容:
soft nofile 1000000 //(最大值为100万)
hard nofile 1000000
//soft nofile表示软性极限,
//hard nofile表示硬性极限,
Java NIO
Java NIO(New IO)在Java4中引入,目的是解决面向流的同步阻塞问题,因此很多人也叫他Non-Block IO 非阻塞IO。
Java NIO也属于IO多路复用模型。
NIO组成3大构件:
Channel 通道
Buffer 缓冲区
Selector 选择器
NIO和OIO的区别
OIO是Java4之前所使用的,面向流的同步阻塞IO,面向字节流或字符流,从字节流(字符流)中读取数据。一次读取一个或者多个不能随意改变指针位置。OIO没有选择器这一个概念
NIO是Java4引入来解决同步阻塞IO的,面向缓冲区的非阻塞IO。每次读取是从通道中读入缓冲区,而写入操作是从缓冲区写入通道中。
可以任意在缓冲区中的位置读取数据。
- NIO如何实现的非阻塞呢?
通过通道和通道的多路复用技术- NIO有选择器这个概念,NIO的实现基于系统的选择器调用。
使用Buffer的方式
- 使用allocate()方法去创建一个buffer对象
- 使用put,将数据写入缓冲池
- 使用filp()可以将写模式换为读模式
- 使用get()可以从缓冲区读取数据
- 读取完毕后,可以使用Buffer.clear()或者是Buffe.compat()方法,将缓冲区转为写模式。
Channel类型
FileChannel文件通道
,用于文件的数据的读写SocketChannel套接字通道
,用于socket套接字TCP连接和数据读写。常用下放的ServerSoketChannel进行连用。ServerSocketChannel服务器套接字通道
,允许监听TCP连接请求,为每个连接的请求创建一个SockeTChannel。DatagramChannl数据报通道
:用于UDP数据的读写。
在使用SocketChannel时,它默认的是同步阻塞,因此需要调用
configureBlocking(false)
来设置,变为异步非阻塞IO。
NIO Selector选择器
选择器的作用就是完成IO的多路复用。一个通道代表一个连接,而通过选择器可以实现同时监控多个连接通道的作用。使得一个线程完成多个通道的监听。
- Selector的IO事件类型
- 可读 OP_READ
- 可写OP_WRITE
- 连接OP_CONNECT 完成了对端的握手,就处于
连接就绪