「我正在参与掘金会员专属活动-源码共读第一期,点击参与」
前言
本篇主要讲解Netty的六大组件Handler, Pipeline, EventLoop, TaskQueue, Future和Promise
往期文章:
- Netty源码分析(一) backlog 参数 - 掘金 (juejin.cn)
- Netty服务端初始化详解 - 掘金 (juejin.cn)
- Netty服务端启动流程分析 - 掘金 (juejin.cn)
- Netty之第一次 TCP 连接时发生了什么 - 掘金 (juejin.cn)
- Netty之服务启动且注册成功之后 - 掘金 (juejin.cn)
- Netty之服务端channel的初始化 - 掘金 (juejin.cn)
- Netty「源码阅读」之 EventLoop 简单介绍到源码分析 - 掘金 (juejin.cn)
- Netty「源码阅读」之怎么解决 Java 的 epoll 空轮询 bug - 掘金 (juejin.cn)
- 什么是零拷贝, 从 Java 到 Netty - 掘金 (juejin.cn)
- ByteBuf 和 ByteBuffer 的区别, ByteBuf 动态扩容源码分析 - 掘金 (juejin.cn)
- Selector 选择器 - 掘金 (juejin.cn)
- Netty「基石」之Reactor模式 - 掘金 (juejin.cn)
Future 和 Promise
Netty中的Future继承于jdk的Future, Promise是对Netty中的Future的扩展
jdk中的Future只能同步等待任务结束才能得到结果Netty中的Future可以同步等待任务结束得到结果, 也可以异步方式得到结果, 但是都要等待任务结束Netty中的Promise不仅有Netty - Future的功能 而且脱离了任务独立存在,只作为两个线程之间传递结果的容器
Netty Future
Netty中的Future可以通过EventLoop.submit()方法来获取
- 可以通过
get()方法来阻塞的获取结果 - 可以通过
getNow()方法非阻塞的获取结果, 没有结果则为null - 可以通过
future.addListener()方法, 在Callable方法执行的线程中, 异步获取返回结果
Netty Promise
Promise相当于一个容器, 可以用户存放各个线程中的结果, 然后让其他线程去获取该结果
ChannelHandler
在Netty中, ServerHandler和ClientHandler存在如下关系
- 都继承于
ChannelInboundHandlerAdapter ChannelInboundHandlerAdapter继承于ChannelHandlerAdapterChannelHandlerAdapter实现了ChannelHandler
因此在Netty中不论是客户端还是服务端的Handler都可以称之为ChannelHandler
在Netty中的ChannelHandler的作用是将当前ChannelHandler的 IO事件 进行处理并传递给同一个ChannelPipeline中的下一个ChannelHandler, 因此在同一个ChannelPipeline中的ChannelHandler就形成了一个责任链
inbound是入站, 客户端到服务端是出站outbound是出站, 服务端到客户端
数据在基于
Netty的服务器或客户端中的处理流程:
- 读取数据
- 解码数据
- 处理数据
- 编码数据
- 发送数据 其中每个过程都会用到
ChannelHandler责任链
Netty Pipeline
每一个Channel中都包含了一个ChannelPipeline, 每个ChannelPipeline中又包含了一个由ChannelHandlerContext构成的双向链表, 在ChannelHandlerContext中又包含了一个ChannelHandler
Channel和ChannelPipeline相互引用
入站和出站
- 当有入站操作的时候, 会从
头开始向后调用Handler, 直到Handler不是处理Inbound操作为止 - 当有出站操作的时候, 会从
尾开始向前调用Handler, 直到Handler不是处理OutBound操作为止
EventLoop 组件
事件循环对象EventLoop的本质是一个单线程执行器, 如果追踪他的继承链, 就会发现该类是继承于JUC的Executor, 同时每一个EventLoop都维护了一个Selector实例, Selector实例会监听注册在其上Channel的 IO事件
- 一个
Selector实例上会注册多个Channel
关于EventLoop组件, 我之前专门出过一篇文章, 从简单分析到源码阅读, 可以去看
Netty「源码阅读」之 EventLoop 简单介绍到源码分析 - 掘金 (juejin.cn)
TaskQueue
在Netty中的NioEventLoop有两个重要的属性, 分别是Selector和TaskQueue, 在之前我专门写过文章写过Selector
在上面, 我们讲解了会在Pipline中调用Handler来处理我们的业务, 那么假如在某一个Handler有一个长时间的操作, 这就势必会造成Pipline的阻塞, 这时我们就可以将这个耗时的处理提交到TaskQueue进行异步的执行
三种使用场景
- 处理用户程序的自定义普通任务的时候
- 处理用户程序的自定义定时任务的时候
- 非当前
Reactor线程调用当前Channel的各种方法的时候
结束
通过本次讲解, 我们对于Netty的六大组件都有了基本的了解, 再配合我们之前的文章, 就对Netty框架的整体架构, 运行流程都有了大概的了解
本文内容到此结束了
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位大佬指出。
我是 宁轩 , 我们下次再见