Netty的常用操作

AOIKUMO#41發表於2024-08-16

EventLoop

  • EventLoop本質上是一個單執行緒執行器,裡面有run方法處理Channel上源源不斷的IO事件。
  • EventLoop繼承了ScheduledExecutorService中的所有方法。

常用方法

  • Future<?> submit(Runnable task) 提交任務
  • ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 迴圈執行,執行前需要等待延時

EventLoopGroup

  • EventLoopGroup是一組EventLoop,Channel一般會呼叫EventLoopGroup的register方法來繫結到其中某個EventLoop,後續該Channel的所有io事件都由它處理。
  • 常用實現:NioEventLoopGroup

常用方法

  • Future<?> shutdownGracefully() 停止所有EventLoop

Channel

常用方法

  • ChannelFuture close() 關閉
  • ChannelFuture closeFuture() 獲取一個ChannelFuture,當通道關閉後會被通知
  • ChannelPipeline pipeline() 獲取管道,用以操作
  • ChannelFuture write(Object msg) 寫資料
  • ChannelFuture writeAndFlush(Object msg) 寫資料並沖刷

可以使用EmbeddedChannel測試Channel

Future & Promise

  • Future是對 JDK Future(java.util.concurrent.Future) 介面的一個擴充套件,以實現非同步操作操作。
  • Promise又對Future進行了擴充套件,允許手動設定非同步操作的結果。常用實現為DefaultPromise。

JDK Future方法

  • V get() 阻塞獲取結果
  • boolean isDone() 任務是否完成
  • boolean isCancelled() 任務是否被取消

Future方法

  • V getNow() 獲取結果,非阻塞,沒有結果返回null
  • Future sync() 阻塞等待任務結束
  • boolean isSuccess() 任務是否成功
  • Throwable cause() 獲取失敗的資訊,非阻塞,沒有失敗返回null
  • Future addListener(GenericFutureListener<? extends Future<? super V>> listener) 新增監聽器,有結果時會通知,非同步獲取結果

Promise方法

  • Promise setSuccess(V result) 標記為成功,設定結果並通知監聽器
  • Promise setFailure(Throwable cause) 標記為失敗,設定失敗原因並通知監聽器

Handler & Pipeline

  • ChannelHandler用來處理Channel上的各種事件,分為入站和出站兩種。
  • Pipeline由一組ChannelHandler串起來組成。
  • 入站處理器通常是ChannelInboundHandlerAdapter的子類,主要用來讀取客戶端資料,寫回結果。(子類呼叫super.channelRead(ctx,msg)繼續向下傳遞)
  • 出站處理器通常是ChannelOutboundHandlerAdapter的子類,主要對寫回結果進行加工
  • 入站處理器從最上面的處理器往下傳遞執行,出站處理器從最底下的處理器往上傳遞執行。注意:nioSocketChannel.writeAndFlush(msg)是從Pipeline的末尾往前找Handler執行,而channelHandlerContext.writeAndFlush(msg)是從當前Handler往前找Handler執行。

ByteBuf

來處理位元組資料。

特點

  • 支援動態擴容
  • 提供了零複製相關方法
  • 堆緩衝區和直接緩衝區: 直接緩衝區效能高,但是分配與釋放慢。
  • 支援記憶體池

記憶體分配器

記憶體池減少了頻繁分配和釋放記憶體的開銷,從而提高了效能。

ByteBufAllocator bba = ByteBufAllocator.DEFAULT; //預設分配器(池化) -Dio.netty.allocator.type={unpooled | pooled} 配置預設方式
ByteBufAllocator bba = PooledByteBufAllocator.DEFAULT; //池化
ByteBufAllocator bba = UnpooledByteBufAllocator.DEFAULT; //非池化

堆緩衝區與直接緩衝區

ByteBuf buf = ByteBufAllocator.DEFAULT.heapBuffer();//堆緩衝區
ByteBuf buf = ByteBufAllocator.DEFAULT.directBuffer();//直接緩衝區

操作

索引:
readerIndex
writerIndex
markedReaderIndex
markedWriterIndex
capacity 容量,容量不夠會擴容,超過maxCapacity會報錯
maxCapacity 最大容量
寫:writerIndex隨著寫移動

  • ByteBuf writeBoolean(boolean value);
  • ByteBuf writeByte(int value);
  • ByteBuf writeShort(int value);
  • ByteBuf writeInt(int value);
  • ByteBuf writeLong(long value);
  • ByteBuf writeChar(int value);
  • ByteBuf writeFloat(float value);
  • ByteBuf writeDouble(double value);
  • ByteBuf writeBytes(ByteBuf src);
  • ByteBuf writeBytes(byte[] src);
  • int writeCharSequence(CharSequence sequence, Charset charset);

讀:readerIndex隨著read相關操作移動

  • boolean readBoolean();
  • byte readByte();
  • short readShort();
  • int readInt();
  • ......

get/set相關操作:獲取或設定指定索引的資料
標記:

  • ByteBuf markReaderIndex(); 讀標記
  • ByteBuf resetReaderIndex(); 將讀索引跳轉到讀標記

其他:

  • ByteBuf slice(int index, int length); 切割

釋放

基於引用計數器,引用計數器到0時釋放記憶體
boolean release(); 引用計數器-1
ByteBuf retain(); 引用計數器+1
釋放時機為最後使用ByteBuf的Handler負責釋放

相關文章