[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 的优点

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

《Netty权威指南》(二)NIO 入门的更多相关文章

  1. Netty权威指南之NIO通信模型

    NIO简介:与Socket和ServerSocket类相对应,NIO提供了SocketChannel和ServerSocketChannel两种不同的套接字通道实现,这两种新通道都支持阻塞和非阻塞两种 ...

  2. Netty权威指南

    Netty权威指南(异步非阻塞通信领域的经典之作,国内首本深入剖析Netty的著作,全面系统讲解原理.实战和源码,带你完美进阶Netty工程师.) 李林锋 著   ISBN 978-7-121-233 ...

  3. 《Netty权威指南》

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

  4. 《Netty 权威指南(第2 版)》目录

    图书简介:<Netty 权威指南(第2 版)>是异步非阻塞通信领域的经典之作,基于最新版本的Netty 5.0 编写,是国内很难得一见的深入介绍Netty 原理和架构的书籍,也是作者多年实 ...

  5. netty权威指南学习笔记二——netty入门应用

    经过了前面的NIO基础知识准备,我们已经对NIO有了较大了解,现在就进入netty的实际应用中来看看吧.重点体会整个过程. 按照权威指南写程序的过程中,发现一些问题:当我们在定义handler继承Ch ...

  6. 《Netty权威指南》目录

    一.基础篇 走进Java NIO 1. Java 的 I/O 演进之路:https://www.cnblogs.com/zengzhihua/p/9930652.html 2. NIO 入门:http ...

  7. netty权威指南学习笔记六——编解码技术之MessagePack

    编解码技术主要应用在网络传输中,将对象比如BOJO进行编解码以利于网络中进行传输.平常我们也会将编解码说成是序列化/反序列化 定义:当进行远程跨进程服务调用时,需要把被传输的java对象编码为字节数组 ...

  8. 《Netty权威指南》笔记

    第1章 Java的I/O演进之路 1.1 Linux网络I/O模型 fd:file descriptor,文件描述符.linux内核将所有外部设备都看作一个文件来操作,对文件的读写会调用内核提供的命令 ...

  9. Netty权威指南(笔记一)

    转载:http://blog.csdn.net/clarkkentyang/article/details/52529785 第一章(略) 第二章 NIO入门 2.1传统的BIO编程(同步阻塞I/O服 ...

  10. Netty权威指南之AIO编程

    由JDK1.7提供的NIO2.0新增了异步的套接字通道,它是真正的异步I/O,在异步I/O操作的时候可以传递信号变量,当操作完成后会回调相关的方法,异步I/o也被称为AIO,对应于UNIX网络编程中的 ...

随机推荐

  1. (树)Subtrees -- hdu -- 5524

    http://acm.hdu.edu.cn/showproblem.php?pid=5524 Subtrees Time Limit: 2000/1000 MS (Java/Others)    Me ...

  2. spark的shuffle机制

    对于大数据计算框架而言,Shuffle阶段的设计优劣是决定性能好坏的关键因素之一.本文将介绍目前Spark的shuffle实现,并将之与MapReduce进行简单对比.本文的介绍顺序是:shuffle ...

  3. Mysql 基本的增删改查

    创建数据库 create  database 库名; 删除数据库 drop database  库名; 进入数据库 use 库名; 查看所有的表 show tables; 创建表  字段名  数据类型 ...

  4. 2.Django模型

    ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...

  5. Linux下SVN配置hook经验总结

    前几天给实验室搭建了一个内部测试的开发环境,LAMP.svn提交以及自动部署. 之前没干过这事儿,到最终搞定还是颇费了些周折.总结一下我的经验,主要是hook的自动执行问题. 拿我的post-comm ...

  6. asp.net core 健康检查

    asp.net core 健康检查 ASP.NET Core 2.2 开始,提供了健康检查中间件和库,用来报告应用基础结构组件的运行状况.官方文档在此 运行状况检查由应用程序作为 HTTP 终结点公开 ...

  7. 动态执行 VB.NET 和 C# 代码

    有时候我们需要尝试动态地与一些代码进行交互,而不是只能执行程序内已编死的代码,那该怎么办呢?我首先推荐各种脚本语言,如Javascript.Lua.Python等等,这些脚本语言有很多优秀的第三方类库 ...

  8. ASP .Net C# ---CSV导入导出

    CSV和Excel大致相同  复制下来 数据传到方法里面就可以了 /// <summary> /// DataTable数据写入CSV文件 /// </summary> /// ...

  9. vue.js 常用组件库

    vux github ui demo:https://github.com/airyland/vux Mint UI 项目主页:http://mint-ui.github.io/#!/zh-cndem ...

  10. 《react精髓》读书笔记

    概述 前几天找react的技术书籍看,找到<react精粹>和<深入浅出React和Redux>.由于<react精粹>是外国人写的,再加上译者奇舞团我也比较喜欢, ...