前言
本篇文章我们就来说说Netty的架构设计,解密高并发之道。学习一个框架之前,我们首先要弄懂它的设计原理,然后再进行深层次的分析。
接下来我们从三个方面来分析 Netty 的架构设计。
Selector 模型
Java NIO 是基于 Selector 模型来实现非阻塞的 I/O。Netty 底层是基于 Java NIO 实现的,因此也使用了 Selector 模型。
Selector 模型解决了传统的阻塞 I/O 编程一个客户端一个线程的问题。Selector 提供了一种机制,用于监督一个或多个 NIO 通道,并识别何时可以使用一个或多个 NIO 通道进行数据传输。这样,一个线程就可以管理多个通道,从而管理多个网络连接。
image-20210804231340262
Selector 提供了选择实行已经就绪的任务的能力。从底层来看,Selector 会轮询 Channel 是否已经准备好实行每个 I/O 操作。Selector 答应单线程处理多个 Channel 。Selector 是一种多路复用的技术。
SelectableChannel
并不是所有的 Channel 都是可以被 Selector 复用的,只有抽象类 SelectableChannel的子类才华被 Selector 复用。
例如,FileChannel 就不能被选择器复用,因为 FileChannel 不是SelectableChannel的子类。
为了与 Selector 一起使用,SelectableChannel必须首先通过register方法来注册此类的实例。此方法返回一个新的SelectionKey对象,该对象表示Channel已经在Selector进行了注册。向Selector注册后,Channel将保持注册状态,直到注销为止。
一个 Channel 最多可以使用任何一个特定的 Selector 注册一次,但是相同的 Channel 可以注册到多个 Selector 上。可以通过调用 isRegistered方法来确定是否向一个或多个 Selector 注册了 Channel。
SelectableChannel可以安全地供多个并发线程使用。
Channel 注册到 Selector
使用 SelectableChannel的register方法,可将Channel注册到Selector。方法接口源码如下:
public final SelectionKey register(Selector sel, int ops) throws ClosedChannelException { return register(sel, ops, null); } public abstract SelectionKey register(Selector sel, int ops, Object att) throws ClosedChannelException;其中各选项说明如下:
- sel:指定 Channel 要注册的 Selector。
- ops : 指定 Selector必要查询的通道的操作。
一个Channel在Selector注册其代表的是一个SelectionKey事件,SelectionKey的范例包括:
<ul><li data-track="21">OP_READ:可读事件;值为:<span style="color: #C7254E; --tt-darkmode-color: #CB2650;"><span style="background-color: #F6F6F6; --tt-darkmode-bgcolor: #1B1B1B;">1 |