[TOC]

2.1 同步阻塞 I/O

采用 BIO 通信模型的服务器,通常由一个独立的 Acceptor 线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行处理,处理完成后,通过输出流返回应答给客户端,线程销毁。

graph TD A1[Socket] -->|读/写| B(Acceptor 线程) A2[Socket] -->|读/写| B A3[Socket] -->|读/写| B B -->|创建| C1[Thread] B -->|创建| C2[Thread] B -->|创建| C3[Thread]

2.2 伪异步 I/O

采用 线程池任务队列 可以实现一种叫做 伪异步 I/O 通信框架。 当有新的客户端接入时,将客户端的 Socket 封装成一个 Task 投递到后端的线程池中进行处理,JDK 的线程池维护着一个消息队列和 N 个活跃线程,对消息队列中的任务进行处理。由于线程池可以设置消息队列的大小和最大线程数,因此它的资源占用时可控的,无论多少个客户端并发访问,都不会导致资源的耗尽和宕机。

graph TD A1[Socket] -->|读/写| B(Acceptor 线程) A2[Socket] -->|读/写| B A3[Socket] -->|读/写| B B --> |提交 Task|P[Thread Pool] B --> |提交 Task|P B --> |提交 Task|P

2.3 NIO

NIO 官方称为 New I/O,目标是要让 Java 支持非阻塞 I/O,所以通常也叫非阻塞 I/O(Non-blocking I/O)。

阻塞模式使用非常简单,但是性能和可靠性都不好,非阻塞模式则正好相反。一般来说,低负载、低并发的应用程序可以选择同步阻塞 I/O 以降低编程复杂度;对于高负载、高并发的网络应用,需要使用 NIO 的非阻塞模式进行开发。

graph TD A1[Socket] -->|读/写| B(Selector) A2[Socket] -->|读/写| B A3[Socket] -->|读/写| B B --> P[Thread]

2.3.1 Buffer、Channel、Selector

1. 缓冲区 Buffer

Buffer 是一个对象,它包含一些要写入或者要读出的数据。在 NIO 库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接从缓冲区读取;在写入数据时,写入到缓冲区。

2. 通道 Channel

网络数据通过 Channel 读取和写入。通道与流的不同之处在于通道是双向的,流只是在一个方向移动,而通道可用于读、写或者二者同时进行。

因为 Channel 是全双工的,所以它可以比流更好地映射底层操作系统的 API。

3. 多路复用器 Selector

多路复用器提供选择已经就绪的任务的能力。Selector 会不断地轮询注册在其上的 Channel,如果某个 Channel 上面发生读或者写事件,这个 Channel 就处于就绪状态,会被 Selector 轮询出来,然后通过 SelectionKey 可以获取就绪 Channel 的集合,进行后续的 I/O 操作。

2.3.2 NIO 服务端序列图

(1)打开 ServerSocketChannel

(2)绑定监听地址 InetSocketAddress

(3)创建 Selector,启动线程

(4)将 ServerSocketChannel 注册到 Selector,监听 ACCEPT

(5)Selector 轮询注册的 Key

(6)handleAccept() 处理新的客户端接入

(7)设置新建客户端连接的 Socket 参数

(8)向 Selector 注册监听读操作 SelectionKey.OP_READ

(9)handleRead() 异步请求消息到 ByteBuffer,收到请求

(10)decode 请求消息

(11)异步写 ByteBuffer 到 SocketChannel,发送响应

2.3.1 NIO 客户端序列图

(1)打开 SocketChannel

(2)设置 SocketChannel 为非阻塞模式,同时设置 TCP 参数

(3)异步连接服务端

(4)判断连接结果,如果连接成功,调到步骤10,否则执行步骤5

(5)向 Reactor 线程的多路复用器注册 OP_CONNECT 事件

(6)创建 Selector,启动线程

(7)Selector 轮询就绪的 Key

(8)handleConnect()

(9)判断连接是否完成,完成执行步骤10

(10)向多路复用器注册读事件 OP_READ

(11)encode 请求消息

(12)异步写 ByteBuffer 到 SocketChannel,发送请求

(13)handleRead() 异步从 SocketChannel 读 ByteBuffer,收到响应

2.4 AIO

NIO 2.0 引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。异步通道提供以下两种方式获取操作结果。

  1. 通过 java.util.concurrent.Future 类表示异步操作的结果;
  2. 在执行异步操作的时候传入一个 java.nio.channels。

CompletionHandler 接口的实现类作为操作完成的回调。

NIO 2.0 的异步套接字通道是真正的异步非阻塞 I/O,对应于 UNIX 网络编程中的事件驱动 I/O(AIO)。它不需要通过多路复用器(Selector)对注册的通道进行轮询操作即可实现异步读写,从而简化了 NIO 的编程模型。

2.5 4 种 I/O 的对比

同步阻塞I/O 伪异步I/O 非阻塞I/O(NIO) 异步I/O(AIO)
客户端个数:I/O线程 1:1 M:N M:1 M:0
I/O(阻塞)类型 阻塞 阻塞 非阻塞 非阻塞
I/O(同步)类型 同步 同步 同步(I/O多路复用) 异步
API使用难度 简单 简单 复杂 一般
调试难度 简单 简单 复杂 复杂
可靠性 非常差 非常差
吞吐量

2.6 选择 Netty 的理由

什么是 Netty

Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

Netty 是一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端。

Netty 的优点

  • 功能强大
  • 使用简单
  • 性能高
  • 安全
  • 社区活跃

转载于:https://www.cnblogs.com/zengzhihua/p/9953646.html

《Netty权威指南》(二)NIO 入门相关推荐

  1. 《Netty权威指南》笔记 —— 第二十、二十一、二十二, 二十三章

    <Netty权威指南>笔记--Netty高级特性 第20章 Netty架构剖析 Reactor通信调度层 职责链 ChannelPipeline 业务逻辑编排层 关键架构质量属性 高性能 ...

  2. 《Netty权威指南 第2版》学习笔记(1)---服务端与客户端开发入门

    前言 Netty权威指南中以时间服务器为入门案例,演示了如何通过Netty完成了服务端与客户端之间的交互过程. 在开始使用Netty开发之前,先回顾一下使用NIO进行服务端开发的步骤. 创建Serve ...

  3. Netty权威指南(四)TCP粘包/拆包问题

    TCP粘包/拆包问题解决之道 上一章 一.介绍 1.1 TCP粘包/拆包问题说明 1.2 TCP粘包/拆包发生的原因 1.3 粘包问题的解决策略 二.未考虑TCP粘包导致的功能异常案例 2.1 Tim ...

  4. 《Netty权威指南》

    <Netty权威指南> 基本信息 作者: 李林锋 出版社:电子工业出版社 ISBN:9787121233432 上架时间:2014-5-29 出版日期:2014 年6月 开本:16开 页码 ...

  5. [201504][Netty 权威指南][第2版][李林锋][著]

    [201504][Netty 权威指南][第2版][李林锋][著] https://github.com/wuyinxian124/nettybook2 基础篇 走进 Java NIO 第 1 章 J ...

  6. IT人物之《Netty权威指南》中文作者 专访华为李林锋:我与Netty那些不得不说的事

    摘要:Netty是业界最流行的NIO框架之一,它的健壮性.功能.性能.可定制性和可扩展性在同类框架中都是首屈一指的.近日,CSDN采访了Netty领域的权威人士李林锋,请他分享Netty开发的经验之道 ...

  7. netty权威指南第一章

    本章内容如下: 5种网络I/O模型的介绍 I/O多路复用的介绍 1.I/O基础入门 在Java1.4之前,Java对I/O的支持不完善,开发人员在开发高性能I/O的程序时,会面临以下问题: 没有数据缓 ...

  8. netty权威指南笔记-以回车换行结尾的消息如何处理半包问题

    概述 TCP底层会发生粘包和拆包,这个是TCP的一个特性.为了减少网络数据传输的次数,TCP总是希望让网络数据到达一定量级的时候才将数据发送出去,而不是缓存区一有数据就马上发送数据. TCP底层会根据 ...

  9. netty权威指南 学习笔记http

    序 李林峰的<netty权威指南>,从Java的NIO开始介绍,后面介绍TCP粘包拆包.中级篇介绍编解码技术. 第10章介绍了HTTP及netty HTTP+XML的技术. 因为xml实际 ...

  10. Netty权威指南带目录完整版.pdf

    2019独角兽企业重金招聘Python工程师标准>>> Netty权威指南带目录完整版.pdf 转载于:https://my.oschina.net/xiaojianyu/blog/ ...

最新文章

  1. webStroage案例
  2. input border IE6 bug
  3. Linux静态库和动态库学习总结
  4. docker随着主机启动 自动启动设置
  5. NSArray中存的是实体时的排序
  6. java 多线程操作map_Java 多线程中ConcurrentHashMap并发读写操作范例
  7. vfp 界面_VFP之老树新花
  8. DOM节点的插入、替换、克隆及删除
  9. Mangos源码分析(9):服务器公共组件实现之环形缓冲区
  10. HTML inline 与block元素
  11. 手机网络延迟测试软件,手机网速延迟测试在线(手机网络延迟测试工具)
  12. Unity 材质之_stander shader
  13. 无线5G CPE与AP
  14. 基于TCP/UDP的NIO服务端/客户端代码实现damo(java)
  15. table 超级详细的 商品订单列表
  16. android直播音频开发准备
  17. 【记录】一次项目架构的设计
  18. vue的基础练习实例
  19. 10组团队项目-中期总结
  20. 华兴资本获高瓴资本与京东金融等多家机构认购

热门文章

  1. ELK详解(十)——Logstash收集Tomcat日志实战
  2. Redis详解(四)——配置文件详解
  3. docker搭建upload-labs
  4. 关于最近开发小程序中踩过的那些坑
  5. 使用DaemonSet+Taint/Tolerations+NodeSelector部署Nginx Ingress Controller
  6. Salesforce新增Einstein AI支撑的自动化功能
  7. storage相关网站
  8. 解决flash builder 4.6安装过程中安装程序遇到错误(-1)
  9. 子DIV块中设置margin-top时影响父DIV块位置的解决办法
  10. WAP入门之WMLScript与JavaScrpt的不同之处