一.五种IO模型
1.阻塞式IO
一般通过在 while(true) 循环中服务端会 调用 accept() 方法等待接收客户端的连接 的方式监听请求,请求一旦接收到一个连 接请求,就可以建立通信套接字在这个通 信套接字上进行读写 *** 作,此时不能再接 收其他客户端连接请求,只能等待同当前 连接的客户端的 *** 作执行完成, 不过可以 通过多线程来支持多个客户端的连接。
2.非阻塞式IO
和阻塞 IO 类比,内核会立即返回,返回后 获得足够的 CPU 时间继续做其它的事情。 用户进程第一个阶段不是阻塞的,需要不断 的主动询问 kernel 数据好了没有;第二个 阶段依然总是阻塞的。
3.IO复用
IO 多路复用(IO multiplexing),也称事件 驱动 IO(event-driven IO),就是在单个线 程里同时监控多个套接字,通过 select 或 poll 轮询所负责的所有 socket,当某个 socket 有数据到达了,就通知用户进程。 IO 复用同非阻塞 IO 本质一样,不过利用 了新的 select 系统调用,由内核来负责本 来是请求进程该做的轮询 *** 作。看似比非 阻塞 IO 还多了一个系统调用开销,不过 因为可以支持多路 IO,才算提高了效率。 进程先是阻塞在 select/poll 上,再是阻 塞在读 *** 作的第二个阶段上。
select/poll 的几大缺点: (1)每次调用 select,都需要把 fd 集合从用户态拷贝到 内核态,这个开销在 fd 很多时会很大 (2)同时每次调用 select 都需要在内核遍历传递进来的 所有 fd,这个开销在 fd 很多时也很大 (3)select 支持的文件描述符数量太小了,默认是1024 epoll(Linux 2.5.44内核中引入,2.6内核正式引入,可被用 于代替 POSIX select 和 poll 系统调用): (1)内核与用户空间共享一块内存 (2)通过回调解决遍历问题 (3)fd 没有限制,可以支撑10万连接
fd:文件标记
4.信号驱动 I/O
信号驱动 IO 与 BIO 和 NIO 最大的区别就在 于,在 IO 执行的数据准备阶段,不需要轮 询。 如图所示:当用户进程需要等待数据的时候 ,会向内核发送一个信号,告诉内核我要什 么数据,然后用户进程就继续做别的事情去 了,而当内核中的数据准备好之后,内核立 马发给用户进程一个信号,说”数据准备好 了,快来查收“,用户进程收到信号之后, 立马调用 recvfrom,去查收数据。
5.异步式 IO
异步 IO 真正实现了 IO 全流程的非阻塞。 用户进程发出系统调用后立即返回,内核 等待数据准备完成,然后将数据拷贝到用 户进程缓冲区,然后发送信号告诉用户进 程 IO *** 作执行完毕(与 SIGIO 相比,一 个是发送信号告诉用户进程数据准备完毕, 一个是 IO执行完毕)。
6.总结
一个场景,去打印店打印文件。
• 同步阻塞 直接排队,别的啥也干不成,直到轮到 你使用打印机了,自己打印文件
• Reactor 拿个号码,回去该干嘛干嘛,等轮到你 使用打印机了,店主通知你来用打印机, 打印文件
• Proactor 拿个号码,回去该干嘛干嘛,等轮到你 使用打印机了,店主直接给你打印好文件, 通知你来拿
二.Netty
1.了解Netty
Netty是网络应用开发框架
1)异步
2)事件驱动
3)基于 NIO
适用于:
• 服务端
• 客户端
• TCP/UDP/HTTP
2.Netty 特性
高性能的协议服务器:
• 高吞吐
• 低延迟
• 低开销
• 零拷贝
• 可扩容
• 松耦合: 网络和业务逻辑分离
• 使用方便、可维护性好
3.Netty 兼容性
JDK 兼容性:
• Netty 3.x: JDK5
• Netty 4.x: JDK6
• Netty 5.x: 已废弃
协议兼容性:
• 兼容大部分通用协议
• 支持自定义协议
嵌入式:
• HTTP Server
• HTTPS Server
• WebSocket Server
• TCP Server
• UDP Server
• In VM Pipe
4.Netty基本概念
• Channel 通道,Java NIO 中的基础概念,代表一个打开的连接,可执行读取/写入 IO *** 作。 Netty 对 Channel 的所有 IO *** 作都是非阻塞的。
• ChannelFuture Java 的 Future 接口,只能查询 *** 作的完成情况,或者阻塞当前线程等待 *** 作完 成。Netty 封装一个 ChannelFuture 接口。 我们可以将回调方法传给 ChannelFuture,在 *** 作完成时自动执行。
• Event & Handler Netty 基于事件驱动,事件和处理器可以关联到入站和出站数据流。
• Encoder & Decoder 处理网络 IO 时,需要进行序列化和反序列化,转换 Java 对象与字节流。 对入站数据进行解码,基类是 ByteToMessageDecoder。 对出站数据进行编码,基类是 MessageToByteEncoder。
• ChannelPipeline 数据处理管道就是事件处理器链。 有顺序、同一 Channel 的出站处理器和入站处理器在同一个列表中。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)