鍍金池/ 教程/ Java/ 豐富的緩沖實現(xiàn)
Netty 實現(xiàn) WebSocket 聊天功能
總結
寫個時間客戶端
寫個丟棄服務器
問題
開始之前
關閉你的應用
開始
用POJO代替ByteBuf
總結
架構總覽
豐富的緩沖實現(xiàn)
解決
寫個應答服務器
I/O API 統(tǒng)一的異步 I/O API
適用快速開發(fā)的高級組件
處理一個基于流的傳輸
Netty 實現(xiàn)聊天功能
基于攔截鏈模式的事件模型
寫個時間服務器
查看收到的數(shù)據(jù)

豐富的緩沖實現(xiàn)

Netty 使用自建的 buffer API,而不是使用 NIO 的 ByteBuffer 來表示一個連續(xù)的字節(jié)序列。與 ByteBuffer 相比這種方式擁有明顯的優(yōu)勢。Netty 使用新的 buffer 類型 ByteBuf,被設計為一個可從底層解決 ByteBuffer 問題,并可滿足日常網(wǎng)絡應用開發(fā)需要的緩沖類型。這些很酷的特性包括:

  • 如果需要,允許使用自定義的緩沖類型。
  • 復合緩沖類型中內置的透明的零拷貝實現(xiàn)。
  • 開箱即用的動態(tài)緩沖類型,具有像 StringBuffer 一樣的動態(tài)緩沖能力。
  • 不再需要調用的flip()方法。
  • 正常情況下具有比 ByteBuffer 更快的響應速度。

更多信息請參考:io.netty.buffer 包描述

Extensibility 可擴展性

ByteBuf 具有豐富的操作集,可以快速的實現(xiàn)協(xié)議的優(yōu)化。例如,ByteBuf 提供各種操作用于訪問無符號值和字符串,以及在緩沖區(qū)搜索一定的字節(jié)序列。你也可以擴展或包裝現(xiàn)有的緩沖類型用來提供方便的訪問。自定義緩沖式仍然實現(xiàn)自 ByteBuf 接口,而不是引入一個不兼容的類型

Transparent Zero Copy 透明的零拷貝

舉一個網(wǎng)絡應用到極致的表現(xiàn),你需要減少內存拷貝操作次數(shù)。你可能有一組緩沖區(qū)可以被組合以形成一個完整的消息。網(wǎng)絡提供了一種復合緩沖,允許你從現(xiàn)有的任意數(shù)的緩沖區(qū)創(chuàng)建一個新的緩沖區(qū)而無需沒有內存拷貝。例如,一個信息可以由兩部分組成;header 和 body。在一個模塊化的應用,當消息發(fā)送出去時,這兩部分可以由不同的模塊生產(chǎn)和裝配。

<pre> +--------+----------+
 | header |   body   |
 +--------+----------+
 </pre>

如果你使用的是 ByteBuffer ,你必須要創(chuàng)建一個新的大緩存區(qū)用來拷貝這兩部分到這個新緩存區(qū)中。或者,你可以在 NiO做一個收集寫操作,但限制你將復合緩沖類型作為 ByteBuffer 的數(shù)組而不是一個單一的緩沖區(qū),打破了抽象,并且引入了復雜的狀態(tài)管理。此外,如果你不從 NIO channel 讀或寫,它是沒有用的。

    // 復合類型與組件類型不兼容。
    ByteBuffer[] message = new ByteBuffer[] { header, body };

通過對比, ByteBuf 不會有警告,因為它是完全可擴展并有一個內置的復合緩沖區(qū)。

    // 復合類型與組件類型是兼容的。
    ByteBuf message = Unpooled.wrappedBuffer(header, body);

    // 因此,你甚至可以通過混合復合類型與普通緩沖區(qū)來創(chuàng)建一個復合類型。
    ByteBuf messageWithFooter = Unpooled.wrappedBuffer(message, footer);

    // 由于復合類型仍是 ByteBuf,訪問其內容很容易,
    //并且訪問方法的行為就像是訪問一個單獨的緩沖區(qū),
    //即使你想訪問的區(qū)域是跨多個組件。
    //這里的無符號整數(shù)讀取位于 body 和 footer
    messageWithFooter.getUnsignedInt(
         messageWithFooter.readableBytes() - footer.readableBytes() - 1);

Automatic Capacity Extension 自動容量擴展

許多協(xié)議定義可變長度的消息,這意味著沒有辦法確定消息的長度,直到你構建的消息?;蛘?,在計算長度的精確值時,帶來了困難和不便。這就像當你建立一個字符串。你經(jīng)常估計得到的字符串的長度,讓 StringBuffer 擴大了其本身的需求。

    // 一種新的動態(tài)緩沖區(qū)被創(chuàng)建。在內部,實際緩沖區(qū)是被“懶”創(chuàng)建,從而避免潛在的浪費內存空間。
    ByteBuf b = Unpooled.buffer(4);

    // 當?shù)谝粋€執(zhí)行寫嘗試,內部指定初始容量 4 的緩沖區(qū)被創(chuàng)建
    b.writeByte('1');

    b.writeByte('2');
    b.writeByte('3');
    b.writeByte('4');

    // 當寫入的字節(jié)數(shù)超過初始容量 4 時,
    //內部緩沖區(qū)自動分配具有較大的容量
    b.writeByte('5');

Better Performance 更好的性能

最頻繁使用的緩沖區(qū) ByteBuf 的實現(xiàn)是一個非常薄的字節(jié)數(shù)組包裝器(比如,一個字節(jié))。與 ByteBuffer 不同,它沒有復雜的邊界和索引檢查補償,因此對于 JVM 優(yōu)化緩沖區(qū)的訪問更加簡單。更多復雜的緩沖區(qū)實現(xiàn)是用于拆分或者組合緩存,并且比 ByteBuffer 擁有更好的性能。

上一篇:寫個丟棄服務器下一篇:解決