Netty「基础」之六大组件

1,290 阅读4分钟

「我正在参与掘金会员专属活动-源码共读第一期,点击参与

前言

本篇主要讲解Netty的六大组件Handler, Pipeline, EventLoop, TaskQueue, Future和Promise

往期文章:

Future 和 Promise

Netty中的Future继承于jdkFuture, 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中, ServerHandlerClientHandler存在如下关系

  • 都继承于ChannelInboundHandlerAdapter
  • ChannelInboundHandlerAdapter继承于ChannelHandlerAdapter
  • ChannelHandlerAdapter实现了ChannelHandler

因此在Netty中不论是客户端还是服务端的Handler都可以称之为ChannelHandler

image.png

Netty中的ChannelHandler的作用是将当前ChannelHandler的 IO事件 进行处理并传递给同一个ChannelPipeline中的下一个ChannelHandler, 因此在同一个ChannelPipeline中的ChannelHandler就形成了一个责任链

  • inbound 是入站, 客户端到服务端是出站
  • outbound 是出站, 服务端到客户端

数据在基于Netty的服务器或客户端中的处理流程:

  • 读取数据
  • 解码数据
  • 处理数据
  • 编码数据
  • 发送数据 其中每个过程都会用到ChannelHandler责任链 image.png

Netty Pipeline

每一个Channel中都包含了一个ChannelPipeline, 每个ChannelPipeline中又包含了一个由ChannelHandlerContext构成的双向链表, 在ChannelHandlerContext中又包含了一个ChannelHandler

  • ChannelChannelPipeline相互引用

image.png

入站和出站

  • 当有入站操作的时候, 会从开始向后调用Handler, 直到Handler不是处理Inbound操作为止
  • 当有出站操作的时候, 会从开始向前调用Handler, 直到Handler不是处理OutBound操作为止

image.png

EventLoop 组件

事件循环对象EventLoop的本质是一个单线程执行器, 如果追踪他的继承链, 就会发现该类是继承于JUCExecutor, 同时每一个EventLoop都维护了一个Selector实例, Selector实例会监听注册在其上Channel的 IO事件

  • 一个Selector实例上会注册多个Channel

关于EventLoop组件, 我之前专门出过一篇文章, 从简单分析到源码阅读, 可以去看 Netty「源码阅读」之 EventLoop 简单介绍到源码分析 - 掘金 (juejin.cn)

TaskQueue

Netty中的NioEventLoop有两个重要的属性, 分别是SelectorTaskQueue, 在之前我专门写过文章写过Selector

在上面, 我们讲解了会在Pipline中调用Handler来处理我们的业务, 那么假如在某一个Handler有一个长时间的操作, 这就势必会造成Pipline的阻塞, 这时我们就可以将这个耗时的处理提交到TaskQueue进行异步的执行

三种使用场景

  • 处理用户程序的自定义普通任务的时候
  • 处理用户程序的自定义定时任务的时候
  • 非当前Reactor线程调用当前Channel的各种方法的时候

结束

通过本次讲解, 我们对于Netty的六大组件都有了基本的了解, 再配合我们之前的文章, 就对Netty框架的整体架构, 运行流程都有了大概的了解




本文内容到此结束了

如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。

如有错误❌疑问💬欢迎各位大佬指出。

我是 宁轩 , 我们下次再见