设为首页 加入收藏

TOP

Netty源码学习3——Channel ,ChannelHandler,ChannelPipeline(二)
2023-09-09 10:26:03 】 浏览:119
Tags:Netty Channel ChannelHandler ChannelPipeline
程使用Selector监听多路IO的Accept事件,然后将这些套接字交给上面的WorkerGroup,so这里NioServerSocketChannel注册到bossGroup中

bossGroup并不会自己进行注册,而是使用next方法找到自己的小弟——EventLoop,进行注册

image-20230827190208865

这里会使用到EventExecutorChooser进行选择EventLoop,Netty自带两种策略

  • 如果EventLoopGroup中的EventLoop是2的幂次个,那么使用PowerOfTwoEventExecutorChooser

    image-20230827190446255

    它使用取模在众多EventLoop中选择一个

  • 如果EventLoopGroup中的EventLoop不是2的幂次个,那么使用GenericEventExecutorChooser,直接对EventLoop个数进行取模

选择完EventLoop后,会调用EventLoop的注册方法,最终会使用AbstractUnsafe#register,其中会先判断执行的线程是不是EventLoop线程,如果不是那么会将任务提交到EventLoop中执行,源码如下:

image-20230827190732474

注册的即将当前Channel注册到Selector,并且attachment指定为当前Channel,这样NioEventLoop在进行IO多路复用的的时候,可通过attachment方法拿到当前Channel

image-20230827191127338

注册结束后会使用ChannelPipeline触发channelRegistered事件,关于ChannelPipeline下一篇博客中进行学习。

在这一步,还会触发NioEventLoop线程的启动,进行事件循环,在一个死循环中使用Selector监听这个Channel的IO事件,并处理其他调度任务,异步任务。(如何启动NioEventLoop线程的——Netty源码学习2——NioEventLoop的执行#NioEventLoop的启动

三丶ChannelPipeline

image-20230827214728636

上面我们说到一个Channel的实例化会触发ChannelPipeline的实例化。ChannelPipeline 和 ChannelHandler 也是我们在平时应用开发的过程中打交道最多的组件,通常程序员使用Netty进行开发只需要将自己定义的ChannelHandler加入到ChannelPipeline中。

ChannelPipeline即是ChannelHandler的流水线,ChannelPipeline 可以看作是 ChannelHandler 的容器载体,它是由一组 ChannelHandler 实例组成的,内部通过双向链表将不同的 ChannelHandler 链接在一起,如下图所示。当有 I/O 读写事件触发时,ChannelPipeline 会依次调用 ChannelHandler 列表对 Channel 的数据进行拦截和处理。

image-20230827164029646

1.ChannelHandlerContext

ChannelHandlerContext 用于保存 ChannelHandler 上下文,其包含了 ChannelHandler 生命周期的所有事件,如 connect、bind、read、flush、write、close 等。

2.ChannelInboundHandler 和 ChannelOutboundHandler

在客户端与服务端通信的过程中,数据从客户端发向服务端的过程叫出站,反之称为入站。数据先由一系列 InboundHandler 处理后入站,然后再由相反方向的 OutboundHandler 处理完成后出站。

3.DefaultChannelPipeline

image-20230827215052052

DefaultChannelPipeline是netty中ChannelPipeline的默认实现,内部保存了HeadContext,和TailContext分别作为链表的头和尾

image-20230827223142192

可以看到HeadContext即是ChannelOutboundInvoker(出站处理器)也是ChannelInboundInvoker(出站处理器),这是因为网络数据写入操作的入口就是由 HeadContext 节点完成的。HeadContext 作为 Pipeline 的头结点负责读取数据并开始传递 入站事件,当数据处理完成后,数据会反方向经过各个 ChannelOutboundInvoker的处理,最终传递到 HeadContext。

而TailContext只实现了ChannelInboundInvoker,它是最后一个ChannelInboundInvoker,用于结束入站事件的传播。

4.ChannelInboundHandler&ChannelOutboundHandler

二者都是ChannelHandler的子接口,其方法的声明对于了Netty中对事件的抽象

image-20230827224300434

4.1 ChannelInboundHandler

方法名&事件
channelRegistered 当Channel注册到它的EventLoop并且能够处理I/O时调用
channelUnregistered 当Channel从它的EventLoop中注销并且无法处理任何I/O时调用
channelActive 当Channel处理于活动状态时被调用
channelInactive 不再是活动状态且不再连接它的远程节点时被调用
channelReadComplete 当Channel上的一个读操作完成时被调
channelRead 当从Channel读取数据时被调用
channelWritabilityChanged 当Channel的可写状态发生改变时被调用
userEventTriggered 当ChannelInboundHandler.fireUserEventTriggered()方法被调用时触发

4.2 ChannelOutBoundHandler

方法名&事件
bind 当请求将Channel绑定到本地地址时被调用
connet 当请求将Channel连接到远程节点时被调用
disconnect 当请求将Channel从远程节点断开时调用
close 当请求关闭Channel时调用
deregister 当请求将Channel从它的EventLoop注销时调用
read 当请求从Channel中读取数据时调用
flush 当请求通过Channel将入队数据冲刷到远程节点时调用
write 当请求通过Channel将数据写入远程节点时被调用

四丶总结

此篇初探了Channel,ChannelPipeline,ChannelContext,ChannelHandler之间的关系,深入学习了Netty中的Nio Channel是怎么和jdk中的Channel组织起来的。

上面我们说到在Netty中,NioEventLoop是事件的调度中心,它控制了Io事件和其他任务的调度,但是io事件的处理是依赖ChannelHandler的,多个ChannelHandler又由ChannelPipline组装成流水线依次执行

那么一个网络请求在Netty中是

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇微服务网关 —— SpringCloud Net.. 下一篇【教程分享】Docker搭建Zipkin,..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目