并发编程 | Netty - [常用组件概要]

Bootstrap & ServerBootstrap

作用

  • 用于引导 Netty 应用
  • 可以对 Netty 进行配置
  • Bootstrap 用于引导客户端,ServerBootstrap 用于引导服务端

常用方法
配置 EventLoop
group()

  • 服务端需要配置两个,通常叫做 boss、workers
  • 客户端只需要配置一个

配置服务端通道实现类
channel()

ServerChannel 添加配置
option()

为接受到的通道添加配置
childOption()

为 boss 配置业务处理类
handler()

为 worker 配置业务处理类
childHandler()

服务端绑定端口
bind()

客户端连接服务器
connect()

Channel

作用

  • Netty 网络通讯的组件,用于网络 IO 操作
  • 支持关联的 IO 的操作,以及与之对应的处理逻辑
  • 可以获取相关信息,如状态、配置等
  • 异步调用的,会立即返回 ChannelFuture
  • 实现丰富,以应对不同协议、不同阻塞类型
    • NioSocketChannel:异步,客户端,TCP
    • NioServerSocketChannel:异步,服务端,TCP
    • NioDatagramChannel:异步,UDP
    • NioSctpChannel:异步,客户端,SCTP
    • NioSctpServerChannel:异步,服务端,SCTP

常用方法
获取 Pipeline
Pipeline()

获取配置
config()

获取访问地址
remoteAddress()

写出并刷新
writeAndFlush()

Future & ChannelFuture

作用

  • 用于异步监听操作的执行结果
  • 可以配合 FutureListener 机制使用

常用方法
返回通道
channel()

等待异步操作执行完成
sync()
注意这个方法是同步的
它是同步的等待,但被等待的是个异步操作

添加监听器
addListener()

Selector

作用

  • Netty 网络通讯的组件,用于实现多路复用,做到一个线程监管多个 Channel
  • 集成在 EnentLoop 中,其上级对象叫 chooser
  • 可以对 EnentLoop 中的通道进行轮询,并在其就绪时选中

更多信息参考 基础 | NIO - [Selector]

ChannelHandler

作用

  • Netty 网络通讯的组件
    • 可以处理 IO 事件
    • 也可以拦截 IO 事件,并将 IO 事件转发给 Pipeline 的下一个 handler
  • 多个 ChannelHandler 可以协同处理业务
  • 很类似过滤器
  • 本身是个接口,提供丰富的待实现方法
    • 接口分出两个分支
      • ChannelInboundHandler:负载处理进站 IO 事件
        用于处理 从对方流向自己 的 IO 事件,比如作为客户端接受服务端响应
      • ChannelInboundHandler:负载处理出站 IO 事件
        用于处理 从自己流向对方 的 IO 事件,比如作为客户端向服务端发请求
      • 其实还有个 ChannelDuplexHandler,但使用场景很少 (违反单一职责违反的太明显了)
    • 接口和两个分支接口,各自有一个配置模式实现
    • 对应类图如下
      在这里插入图片描述

常用方法
激活时回调
channelActive()

取消激活时回调
channelInactive()

读取时回调
channelRead()

读取完成时回调
channelReadComplete()

写出时回调
channelWrite()

写出完成时回调
channelWriteComplete()

异常时回调
exceptionCaught()

handler 加入时回调
handlerAdded()
hander 已经加入了对应的 context 并可以真正处理事件时触发

  • 相当于一个 Channel 注册到 Selector 并完成准备工作时触发
  • 相当于一个新连接建立完全后触发

handler 移除时回调
handlerRemoved()

Pipeline & ChannelPipeline

作用

  • 作为 Handler 的集合,负责处理、拦截出入站 IO 事件
  • 很类似过滤器栈,责任链模式
  • 可以完全控制 IO 事件的处理方式,并控制各个 ChannelHandler 如何相互调用

结构

  • 每个 Channel 都有且仅有一个 Pipeline
    二者关系参考 并发编程 | Netty - [Reactor 模型]
  • ChannelPipeline 本质上是一个双向链表
  • 链表的节点类型是 ChannelHandlerContextChannelHandlerContext 内部是 ChannelHandler
  • 通常不同 Pipeline 中的 ChannelHandler 不共享
    技术上是可以做到共享的,但是一旦共享就需要处理线程安全问题,影响性能
  • 入站、出站的 ChannelHandler 在同一个链表中,但不会互相影响,Handler 与当前操作不符时会直接放行

在这里插入图片描述

常用方法
头部追加 Handler
addFirst()

尾部追加 Handler
addLast()

ChannelHandlerContext

作用

  • Pipeline 中直接节点的类型,里面封装了 ChannelHandler
    • ChannelHandler 中方法普遍带有 ChannelHandlerContext 类型的参数
    • 可以从中获取关键对象,如 pipeline()channel()
    • 可以直接调用 ChannelHandler 的方法,如 writeAndFlush()

ChannelOption

作用

  • 用于配置 Netty 中的 Channel

常用配置
SO_BACKLOG
配置 TCP/IP 协议中,初始化服务器可连接队列的大小

SO_KEEPALIVE
配置是否保持连接存活

ChannelGroup

作用

  • Channel 的容器,用于存储、管理所有注册在其中的 Channel

常用方法
注册 channel
addd()

广播写
writeAndFlush()

NioEventLoop

作用

  • 每个 NioEventLoop 包含一个 Selector
    相当于经典 Reactor 模型中一个 Reactor + Handler
  • 保持有一个任务队列,每一轮轮询并处理事件后,可以执行其中的任务
  • 以事件循环的方式处理绑定在其中的 Socket
    • select:通过集成的 Selector 监听绑定的 Socket 的关注事件
    • processSelectedKeys:处理选中的 key,即处理就绪的事件
    • runAllTasks:执行任务队列中的所有任务

在这里插入图片描述

NioEventLoopGroup

作用

  • 可以包含多个 NioEventLoop
    • 每个 NioEventLoop 对应一个 Selector 和一个线程
    • 通常一个 ServerSocketChannel 对应一个 NioEventLoop
  • 可以分为两组协同作业(常见于服务端)
    • BossGroup:负责 accept,通常只有一个 NioEventLoop
    • WorkerGroup:负责读写,通常有多个 NioEventLoop
  • 通过 chooser.next() 接口获取某个 NioEventLoop 进行处理当前的 SocketChannel

常用方法
优雅停机(断开连接,关闭线程)
shutdownGracefull()

Unpooled

作用

  • Netty 提供的缓冲区操作工具类

常用方法
初始化 ByteBuf
copiedBuffer(CharSequence, Charset)

开辟 ByteBuf
buffer(size)

ByteBuf

作用

  • Netty 提供的字节缓冲区
  • 效率比 NIO 的 ByteBuffer 高
  • 不需要反转 flip()

重要属性
capacity
容量,是 ByteBuf 内部用于存放数据的容器的大小,而不是实际数据量
统一由 capacity() 返回,真实获取方式随具体实现变化,如 array.lengthcapacity

readIndex
下一个读入的位置

writeIndex
下一个读入的位置

属性关系图
在这里插入图片描述

常用方法
长度
capacity()

数据写入
writeByte
向缓冲区写入字节
writerIndex 会 +1

读取数据
readByte()
从缓冲区读取字节
readerIndex 会 +1

获取读指针
readerIndex()
读指针指向即将被读的位置

获取写指针
writerIndex()
写指针指向即将被写的位置

读取数据
getByte(index)
获取指定 index 的字节
不影响 readIndex

按 index 范围读取字符串
getCharSequence(start,end,charset)

是否有数组
hasArray()
如果返回 true 才能安全的 array()arrayOffset()

获取 byte 数组
array()

获取字节数组中第一个字节的偏移量
arrayOffset()

获取可读字节数
readableBytes()
参考 属性关系图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值