前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Netty权威指南_netty编程实战

Netty权威指南_netty编程实战

作者头像
全栈程序员站长
发布2022-11-10 20:42:47
3800
发布2022-11-10 20:42:47
举报

大家好,又见面了,我是你们的朋友全栈君。

2.1 BIO

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

graph TD

A1[Client] –>|读/写| B(Acceptor 线程)

A2[Client] –>|读/写| B

A3[Client] –>|读/写| B

B –>|创建| C1[Thread]

B –>|创建| C2[Thread]

B –>|创建| C3[Thread]

2.2 伪异步 I/O

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

graph TD

A1[Client] –>|读/写| B(Acceptor 线程)

A2[Client] –>|读/写| B

A3[Client] –>|读/写| 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

C1[Client] –> |读/写| S[Selector]

C2[Client] –> |读/写| S

C3[Client] –> |读/写| S

S –> P[Thread]

2.3.1 Buffer、Channel、Selector

1. 缓冲区 Buffer

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

fb0e045a19fd738c64f6db0d0b2fc672.png
fb0e045a19fd738c64f6db0d0b2fc672.png

public abstract class Buffer {

// Invariants: mark <= position <= limit <= capacity

private int mark = -1;

private int position = 0;

private int limit;

private int capacity;

}

2. 通道 Channel

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

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

d626e18ebdd6d7572228f6ff3bd598e8.png
d626e18ebdd6d7572228f6ff3bd598e8.png

3. 多路复用器 Selector

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

2.3.2 NIO 服务端序列图

839d04adc89dbe9a9ccd31aa3e9d86fe.png
839d04adc89dbe9a9ccd31aa3e9d86fe.png

(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.3 NIO 客户端序列图

cc879f3c6ec01be82920881f6f193100.png
cc879f3c6ec01be82920881f6f193100.png

(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)handleRead() 异步从 SocketChannel 读请求到 ByteBuffer,收到请求

(12)decode 请求消息

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

2.4 AIO

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

通过 java.util.concurrent.Future 类表示异步操作的结果;

在执行异步操作的时候传入一个 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://javaforall.cn/188068.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022年9月28日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 CMQ 版
消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档