Netty关键组件ByteBuf、BootStrap

一、ByteBuf

1.内存结构

ByteBuf本质上引用了一段内存,这段内存可以是堆内也可以是堆外的,然后用引用计数来控制这段内存是否需要被释放,分别使用读写指针来控制对 ByteBuf 的读写,可以理解为是外观模式的一种使用。

ByteBuf 的结构

2.ByteBuf的字节数组的三种模式:

  • 堆缓冲区模式(Heap Buffer)
  • 直接缓冲区模式(Direct Buffer)
  • 复合缓冲区模式(Composite Buffer)

3.ByteBuf的释放

  1. InBound,每个Handler对ByteBuf的处理有以下三种方式:
  • 对原消息不做处理,调用 ctx.fireChannelRead(msg)把原消息往下传,此时不做释放;
  • 将原消息转化为新的消息并调用 ctx.fireChannelRead(newMsg)往下传,那必须把原消息release掉;
  • 如果已经不再调用ctx.fireChannelRead(msg)传递任何消息,那更要把原消息release掉;
  1. OutBound
    要发送的消息通常由应用所创建,并调用 ctx.writeAndFlush(msg) 进入Handler链。在每一个Handler中的处理类似InBound Message,最后消息会来到HeadHandler,再经过一轮复杂的调用,在flush完成后终将被release掉。

  2. Exception
    多层的异常处理机制,有些异常处理的地方不一定准确知道ByteBuf之前释放了没有,可以在释放前加上引用计数大于0的判断避免异常; 有时候不清楚ByteBuf被引用了多少次,但又必须在此进行彻底的释放,可以循环调用reelase()直到返回true。

source: Netty之ByteBuf的创建和释放

二、BootStrap

Bootstrap是用来组织Netty的各个结构(pipeline,handler,eventloop),并使他们运行起来的类结构。分成两块,一个是客户端引导类Bootstrap,只用1个channel来处理所有的网络交互,另一个是服务端的ServerBootstrap,它提供一个父channel来接受客户端的请求,然后父channel创建多个子channel来用于的通信。

Bootstrap是开发netty客户端的基础,通过Bootstrap的connect方法来连接服务器端。该方法返回的也是ChannelFuture,通过这个我们可以判断客户端是否连接成功,以便我们在连接成功之后,做一些其他的事情。但是在调用connect方法前,我们需要指定EventLoopGroup,channelFactory(不指定这个,就会使用netty默认的channelFactory,但是需要指定channel,初始channel时,同时会初始化channelFactory),ChannelHandler。这些都是必须指定的,不指定就会报异常。

推荐阅读更多精彩内容