分布式之Netty介绍与实战(二)--Netty编程实践

目录

分布式之Netty介绍与实战(一)--Java IO与NIO

分布式之Netty介绍与实战(二)--Netty编程实践

分布式之Netty介绍与实战(三)--Netty线程模型解析

分布式之Netty介绍与实战(四)--Netty编解码编程实战


Netty是什么

Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序

Netty 特性

  • 设计
    • 统一的API,适用于同的协议(阻塞和非阻塞)
    • 基于灵活、可扩展的事件驱动模型SEDA
    • 高度可定制的线程模型
    • 可靠的无连接数据Socket支持(UDP)
  • 性能
    • 更好的吞吐量,低延迟
    • 更省资源
    • 尽量减少必要的内存拷贝
  • 安全
    • 完整的SSL/ TLS和STARTTLS的支持
  • 易用
    • 完善的Java doc,用户指南和样例
    • 仅依赖于JDK1.6(netty 4.x)

Netty 主要组件

  • Netty 主要组件
    • Transport Channel  ---- 对应NIO中的channel
    • EventLoop ---- 对应于NIO中的while循环
    • EventLoopGroup: 多个EventLoop
    • ChannelHandler和ChannelPipeline --- 对应于NIO中的客户逻辑实现handleRead/handleWrite (interceptor pattern
    • ByteBuf ---- 对应于NIO 中的ByteBuffer
    • Bootstrap 和 ServerBootstrap --- 对应NIO中的Selector、ServerSocketChannel等的创建、配置、启动等
  • Netty Server启动主要流程:
    • 设置服务端ServerBootStrap启动参数
    • group(parentGroup, childGroup):
    • channel(NioServerSocketChannel): 设置通道类型
    • handler():设置NioServerSocketChannelChannelHandlerPipeline
    • childHandler(): 设置NioSocketChannelChannelHandlerPipeline
    • 通过ServerBootStrapbind方法启动服务端,bind方法会在parentGroup中注册NioServerScoketChannel,监听客户端的连接请求
    • 会创建一个NioServerSocketChannel实例,并将其在parentGroup中进行注册
  • Netty Server执行主要流程:
    • ØClient发起连接CONNECT请求,parentGroup中的NioEventLoop不断轮循是否有新的客户端请求,如果有,ACCEPT事件触发
    • ØACCEPT事件触发后,parentGroupNioEventLoop会通过NioServerSocketChannel获取到对应的代表客户端的NioSocketChannel,并将其注册到childGroup
    • ØchildGroup中的NioEventLoop不断检测自己管理的NioSocketChannel是否有读写事件准备好,如果有的话,调用对应的ChannelHandler进行处理

Netty Transport - 传输层

  • 提供了统一的API,支持不同类型的传输层
    • OIO -阻塞IO
    • NIO - Java NIO
    •  Epoll -  Linux Epoll(JNI)
    •  Local Transport - IntraVM调用
    •  Embedded Transport - 供测试使用的嵌入传输
    • UDS -  Unix套接字的本地传输

Netty EventLoop

  • EventLoopGroup
    • 包括多个EventLoop
    • 多个EventLoop之间不交互
  • EventLoop
    • 每个EventLoop对应一个线程
    • 所有连接(channel)都将注册到一个EventLoop,并且只注册到一个,整个生命周期中都不会变化
    • 每个EventLoop管理着多个连接(channel)
    • EventLoop来处理连接(Channel)上的读写事件
  • ServerBootstrap
    • 包括2个不同类型的EventLoopGroup:
      • Parent EventLoop:负责处理Accept事件,接收请求
      • Child EventLoop:负责处理读写事件

Netty Buffers - ByteBuf

  • 相比JDK ByteBuffer, 更加易于使用:
    • 为读/写分别维护单独的指针,不需要通过flip()进行读/写模式切换
    • 容量自动伸缩(类似于 ArrayList,StringBuilder)
    • Fluent API (链式调用)
  • 更好的性能
    • 通过内置的CompositeBuffer来减少数据拷贝(Zero copy)
    • 支持内存池,减少GC压力

 

  • ByteBuf通过两个索引(reader indexwriter index)划分为三个区域:
    • reader index前面的数据是已经读过的数据,这些数据可以丢弃
    • 从reader index开始,到writer index之前的数据是可读数据
    • 从writer index开始,为可写区域

Netty Buffers - ByteBuf主要操作

顺序读/写- 改变reader/writer index

  • writeByte()
  • writeLong()
  • writeXXX() - 增加write index
  • readByte()
  • readLong()
  • readXXX() - 增加read index

随机读/写: - 不改变read/write index

  • getXXX(index)
  • setXXX(index, byte)

mark/reset:

  • markReaderIndex()
  • markWriterIndex()
  • resetReaderIndex()
  • resetWriterIndex()
  • writerIndex(index)
  • readerIndex(index)

discardReadBytes方法 - compact

clear方法

查询方法

  • indexOf
  • bytesBefore
  • forEachByte(ByteBufProcessor)

Derived Buffers(衍生缓冲区)

üduplicate()

üslice()

üslice(start, stop)

üunmodifiableBuffer(...),

Derived Buffers(衍生缓冲区)

  • 具有各自的index和mark
  • 返回的 ByteBuf 与原ByteBuf 共享底层存储

缓冲区拷贝

  • copy() 或 copy(int, int)
  • 返回的 ByteBuf 有数据的独立副本

Netty Buffers -  ByteBuf的类型

 

  • 根据内存的位置

  • HeapByteBuf
    • Ø基于数组- 内部为一个字节数组 (byte array)
    • ØhasArray()返回True
    • Øarray()返回其内部的数组,可以对数组进行直接操作
  • DirectByteBuf
    • Ø堆外内存
    • Ø具有更好的性能
    • Ø创建和释放开销更大
  • 根据是否使用内存池
    • Pooled vs Unpooled
  • 根据是否使用Unsafe操作(Unsafe)
  • Safe vs Unsafe

Netty Buffers -  CompositeByteBuf

复合缓冲区(CompositeByteBuf)

  • 多个ByteBuf组合的视图
  • 一个ByteBuf列表,可动态的添加和删除其中的 ByteBuf
  • 可能既包含堆缓冲区,也包含直接缓冲区

Netty Buffers -  ByteBufHolder

ByteBufHolder

  • 除ByteBuf外,还另外存储除有效的实际数据各种属性值

Netty Buffers -  ByteBuf分配

不直接通过new来创建,而是通过ByteBufAllocator来创建

  • UnpooledByteBufAllocator
  • PooledByteBufAllocator

Netty Buffers -  Unpooled工具类

Unpooled 的工具类,它提供了静态的辅助方法来创建未池化的ByteBuf实例

Netty ChannelHandler

ChannelHandler  - 业务处理核心逻辑,用户自定义

Netty 提供2个重要的 ChannelHandler 子接口:

  • ChannelInboundHandler - 处理进站数据和所有状态更改事件
  • ChannelOutboundHandler - 处理出站数据,允许拦截各种操作

Netty Channel状态及转换

Channel的状态及其转换如下图所示:

Netty Channel状态及转换

ChannelHandler 添加到 ChannelPipeline,或者从ChannelPipeline 移除后,对应的方法将会被调用

Netty ChannelInboundHandler

ChannelInboundHandler 回调方法在下表中

  • 当接收到数据或者与之关联的 Channel 状态改变时调用
  • 与 Channel 的生命周期接近

Netty ChannelOutboundHandler

ChannelOutboundHandler回调方法在下表中

Netty ChannelPipeline

ChannelPipeline 是ChannelHandler容器

  • 包括一系列的ChannelHandler 实例,用于拦截流经一个 Channel 的入站和出站事件
  • 每个Channel都有一个其ChannelPipeline
  • 可以修改 ChannelPipeline 通过动态添加和删除 ChannelHandler
  • 定义了丰富的API调用来回应入站和出站事件

Netty ChannelHandlerContext

ChannelHandlerContext表示 ChannelHandler 和ChannelPipeline 之间的关联

  • 在 ChannelHandler 添加到 ChannelPipeline 时创建

ChannelHandlerContext表示 ChannelHandler 和ChannelPipeline 之间的关联

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值