Netty核心组件

川长思鸟来 2022-12-07 15:24 301阅读 0赞

以下内容输出来源:拉勾教育-Java高薪训练营

Netty核心组件

  • 1、bossGroup与WorkerGroup
  • 2、Channel
  • 3、Selector
  • 4、ChannelPipeline与ChannelHandler
  • 5、InBound与OutBound
  • 6、NioEventLoop
  • 7、ServerBootStrap和BootStrap
  • 8、如何自定义Handler

1、bossGroup与WorkerGroup

netty抽象出两组线程池BossGroup用于接收客户端连接,WorkGroup用于处理网络读写。两者类型是NioEventLoopGroup(线程池),由NioEventLoop(线程)组成。每个NioEventLoop表示一个不断循环的,执行任务处理的线程,每个NioEventLoop 都有一个Selector与之对应,用于监听绑定在它上面的网络连接,连接事件都是由该线程来处理。

1、每个 Boss NioEventLoop 会监听 Selector 上连接建立的 accept 事件,然后处理 accept 事件与客户端建立网络连接,生成相应的 NioSocketChannel 对象,一个 NioSocketChannel 就表示一条网络连接。之后会将 NioSocketChannel 注册到某个 Worker NioEventLoop 上的 Selector 中。

2、每个 Worker NioEventLoop 会监听对应 Selector 上的 read/write 事件,当监听到 read/write 事件的时候,会通过 Pipeline 进行处理。一个 Pipeline 与一个 Channel 绑定,在 Pipeline 上可以添加多个 ChannelHandler,每个 ChannelHandler 中都可以包含一定的逻辑,例如编解码等。Pipeline 在处理请求的时候,会按照我们指定的顺序调用 ChannelHandler。

2、Channel

常用的 NIO Channel 类型包括:
NioSocketChannel:对应异步的 TCP Socket 连接。
NioServerSocketChannel:对应异步的服务器端 TCP Socket 连接。

Channel 主要提供了异步的网络 I/O 操作,例如:建立连接、读写操作等。I/O 操作返回的是一个 ChannelFuture 对象,我们通过向 ChannelFuture 上注册监听器来监听 I/O 操作的结果。

ChannelFuture表示IO操作的结果,从命名上看就知道是异步的。

  1. // 返回当前正在进行 IO 操作的通道,客户端通过该方法发送连接
  2. Channel channel();
  3. // 等待异步操作执行完毕,服务端通过该方法监听连接请求
  4. ChannelFuture sync();

3、Selector

Selector 是对多路复用器的抽象,也是 Java NIO 的核心基础组件之一。
在 Selector 内部,会通过系统调用不断地查询这些注册在其上的 Channel 是否有已就绪的 I/O 事件,例如,可读事件(OP_READ)、可写事件(OP_WRITE)或是网络连接事件(OP_ACCEPT)等,而无须使用用户线程进行轮询。

4、ChannelPipeline与ChannelHandler

1、ChannelHandler 接口,封装了很多处理事件(连接、读/写)的方法。

  1. //通道就绪事件
  2. public void channelActive(ChannelHandlerContext ctx);
  3. //通道读取数据事件
  4. public void channelRead(ChannelHandlerContext ctx, Object msg);
  5. //数据读取完毕事件
  6. public void channelReadComplete(ChannelHandlerContext ctx);
  7. //通道发生异常事件
  8. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause);

2、 ChannelPipeline 负责处理和拦截InBound与OutBound的事件和操作

  1. // 把一个业务处理类(handler) 添加到链中的第一个位置
  2. ChannelPipeline addFirst(ChannelHandler... handlers);
  3. //把一个业务处理类(handler) 添加到链中的最后一个位置
  4. ChannelPipeline addLast(ChannelHandler... handlers);

3、ChannelHandlerContext 事件处理器的上下文对象

  1. //关闭通道
  2. ChannelFuture close();
  3. //刷新
  4. ChannelOutboundInvoker flush();
  5. //将数据写到 ChannelPipeline 中当前ChannelHandler 的下一个 ChannelHandler 开始处理(出站)
  6. ChannelFuture writeAndFlush(Object msg);

ChannelPipeline 会将一个 ChannelHandler 处理后的数据作为下一个 ChannelHandler 的输入。
ChannelPipeline 中的事件传播主要依赖于ChannelHandlerContext 实现。
ChannelHandlerContext 抽象的是 ChannleHandler 之间的关系以及 ChannelHandler 与ChannelPipeline 之间的关系。

每个ChannelHandlerContext 包含一个具体的ChannelHandler,同时绑定上面的关系,方便对ChannelHandler调用。

综上,一个 Channel 对应一个 ChannelPipeline,一个 ChannelHandlerContext 对应一个ChannelHandler。
最后,需要注意的是,如果要在 ChannelHandler 中执行耗时较长的逻辑,例如,操作 DB 、进行网络或磁盘 I/O 等操作,一般会在注册到 ChannelPipeline 的同时,指定一个线程池异步执行 ChannelHandler 中的操作。

5、InBound与OutBound

Netty 中定义了两种事件类型:入站(Inbound)事件和出站(Outbound)事件。
入站(Inbound)事件一般由 I/O 线程触发。
出站(Outbound)事件与入站(Inbound)事件相反,一般是由用户触发的。

ChannelPipeline 之上可以注册多个 ChannelHandler(ChannelInboundHandler 或 ChannelOutboundHandler),我们通过责任链模式在 ChannelHandler 注册的时候决定处理 I/O 事件的顺序。

Netty 提供的 ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter 主要是帮助完成事件流转功能的,即自动调用传递事件的相应方法。

6、NioEventLoop

一个 NioEventLoop(线程) 包含了一个 Selector 对象,可以支持多个 Channel 注册在其上,该 NioEventLoop 可以同时服务多个 Channel,每个 Channel 只能与一个 NioEventLoop 绑定,这样就实现了线程与 Channel 之间的关联。
总之,Channel 中的 I/O 操作是由 ChannelPipeline 中注册的 ChannelHandler 进行处理的,而 ChannelHandler 的逻辑都是由相应 NioEventLoop 的那个线程执行的。

NioEventLoop的主要做三件事,监听 I/O 事件、执行普通任务以及执行定时任务。

1、普通任务

用户产生的普通任务提交到普通任务队列,NioEventLoop发现该任务后立即执行,这是一个多生产者,单消费者的队列,Netty 使用该队列将外部用户线程产生的任务收集到一起,并在 Reactor 线程内部用单线程的方式串行执行队列中的任务。

2、定时任务

用户将设置的定时任务加入到定时任务队列中,等待对应的NioEventLoop串行执行。

7、ServerBootStrap和BootStrap

分别代表Netty中服务端和客户端的启动助手,通过它完成各种配置。

  1. //该方法用于服务器端, 用来设置两个 EventLoop
  2. public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup);
  3. //该方法用来设置一个服务器端的通道实现
  4. public B channel(Class<? extends C> channelClass);
  5. //用来给 ServerChannel 添加配置
  6. public <T> B option(ChannelOption<T> option, T value);
  7. //用来给接收到的通道添加配置
  8. public <T> ServerBootstrap childOption(ChannelOption<T> childOption, T value);
  9. //该方法用来设置业务处理类(自定义的 handler)
  10. public ServerBootstrap childHandler(ChannelHandler childHandler);
  11. //该方法用于服务器端, 用来设置占用的端口号
  12. public ChannelFuture bind(int inetPort);
  13. //该方法用于客户端, 用来设置一个 EventLoop
  14. public B group(EventLoopGroup group);
  15. //该方法用于客户端, 用来连接服务器端
  16. public ChannelFuture connect(String inetHost, int inetPort);

8、如何自定义Handler

实现ChannelHandler接口或者实现ChannelInBoundHandlerAdapter

发表评论

表情:
评论列表 (有 0 条评论,301人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Netty 核心组件

    Netty 核心组件 1. 前言 本节我们主要从整体上了解 Netty 有哪些核心组件,很多同学学习完 Netty 虽然会使用,但是只知道如何自定义 Handler

    相关 netty全部核心组件

    看看netty为我们提供的核心组件 一 1. channel:netty中把一个端到端的通信定义为了通道。所谓的端包含但不限于硬件设备,文件。这是对通信的第一层抽象。通

    相关 Netty核心组件

    Netty的核心组件   Channel   回调   Future   事件   ChannelHandler   这些模块代表了不同的类型:资源(事件)、逻