Netty常見面試題2022版

 

 

文章目錄
一  基本概念
1、什麼是 Netty?
2、Netty 的優勢?
3、Netty 有什麼特點?
4、Netty 有哪些應用場景?
5、Netty 的高性能體現在?
6、相比原生 NIO 的優勢?
7、Netty 和 Tomcat 的區別?
8、BIO. NIO. AIO 分別是什麼?
9、Select、Poll、Epoll 的區別?
10、什麼是 Reactor 模型?


二  架構組件
1、Netty 有哪些核心組件?
2、什麼是 EventLoop 和 EventLoopGroup?
3、說說 Netty 的線程模型?
4、Netty 服務端的啓動過程?


三  具體實現
1、Netty 的無鎖化體現在哪裏?
2、如何解決 JDK epoll 空輪詢問題?
3、什麼是拆包和粘包?
4、拆包粘包的解決方案?
5、Netty 如何解決拆包粘包?
6、Netty 零拷貝體現在哪裏?
7、TCP 的長連接和短連接?
8、Netty 長連接、心跳機制瞭解麼?
9、說說 Netty 的對象池技術?
10 有哪些序列化協議?

 

 



一 基本概念

1、什麼是 Netty?

  • Netty 是由 JBOSS 提供的一個 Java 開源框架。
  • Netty 提供異步的、基於事件驅動的網絡應用程序框架,用以快速開發高性能、高可靠性的網絡 IO 程序,是目前最流行的 NIO 框架
  • Netty 在互聯網領域、大數據分佈式計算領域、遊戲行業、通信行業等獲得了廣泛的應用,知名的 Elasticsearch 、Dubbo 框架內部都採用了 Netty。

2、Netty 的優勢?

  • 使用簡單:封裝了 Java 原生 NIO 類庫繁瑣的 API,使用起來更加高效;
  • 功能強大:預置多種編碼能力,支持多種主流協議。同時通過 ChannelHandler 可以進行靈活的拓展,支持很強的定製能力;
  • 高性能:與其它業界主流 NIO 框架相比,Netty 綜合更優。主要體現在吞吐量更高、延遲更低、減少資源消耗以及最小化不必要的內存複製;
  • 社區活躍與穩定:版本更新週期短,BUG 修復速度快,讓開發者可以專注業務本身。

 

3、Netty 有什麼特點?

  • 高併發:Netty 是一款基於 NIO(Nonblocking I/O,非阻塞IO)開發的網絡通信框架。
  • 傳輸快:Netty 使用零拷貝特性,儘量減少不必要的內存拷貝,實現更快的傳輸效率。
  • 封裝好:Netty 封裝了 NIO 操作的很多細節,提供易於使用的 API。

 

4、Netty 有哪些應用場景?

理論上來說,NIO 可以做的事情,Netty 都可以做並且更好。Netty 主要用來做網絡通信

  • RPC 框架的網絡通信工具;
  • 實現一個 HTTP 服務器;
  • 實現一個即時通訊系統;
  • 實現消息推送系統。

 

 

 

5、Netty 的高性能體現在?

  • IO 線程模型:同步非阻塞;
  • 零拷貝:儘量做到不必要的內存拷貝:
  • 內存池設計:使用直接內存,並且可重複利用;
  • 串行化處理讀寫:避免使用鎖帶來的額外開銷;
  • 高性能序列化協議:支持 protobuf 等高性能序列化協議。

 

6、相比原生 NIO 的優勢?

1)易用性:Netty 在 NIO 基礎上封裝了更加人性化的 API,大大降低開發人員的學習成本,同時還提供了很多開箱即用的工具。

2)穩定性:Netty 修復了 Java NIO 較多已知問題,如 select 空轉導致 CPU 100%,TCP 斷線重連,Keep-alive 檢測等問題。

3)高性能:對象池複用(通過對象複用避免頻繁創建和銷燬帶來的開銷)和零拷貝技術。

 

7、Netty 和 Tomcat 的區別?


Netty 和 Tomcat 最大的區別在於對通信協議的支持

  • Tomcat 是基於 Http 協議的本質是一個基於 http 協議的 web 容器而 Netty 不僅支持 HTTP,還能通過編程自定義各種協議,通過 codec 自定義編碼/解碼字節流,完成數據傳輸。
  • Tomcat 需要遵循 Servlet 規範(HTTP 協議的請求-響應模型),而 Netty 不需要受到 Servlet 規範約束,可以發揮 NIO 最大特性。

 

8、BIO. NIO. AIO 分別是什麼?

 

  • BIO(同步阻塞 IO)

服務器實現模式爲一個連接一個線程,即客戶端有連接請求時服務器端就需要啓動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。BIO 方式適用於連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,併發侷限於應用中,JDK 1.4 以前的唯一選擇,但程序直觀簡單易理解。

  • NIO(同步非阻塞 IO)

服務器實現模式爲一個請求一個線程,即客戶端發送的連接請求都會註冊到多路複用器上,多路複用器輪詢到連接有 IO 請求時才啓動一個線程進行處理。NIO 方式適用於連接數目多且連接比較短(輕操作)的架構,比如聊天服務器,併發侷限於應用中,編程比較複雜,JDK 1.4 開始支持。

  • AIO(異步非阻塞 IO)

服務器實現模式爲一個有效請求一個線程,客戶端的 IO 請求都是由 OS 先完成了再通知服務器應用去啓動線程進行處理。 AIO 方式使用於連接數目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用 OS 參與併發操作,編程比較複雜,JDK 1.7 開始支持。

 

 

9、Select、Poll、Epoll 的區別?   

ref:  https://www.cnblogs.com/aspirant/p/9166944.html

 

10、什麼是 Reactor 模型?

 

 

二   架構組件

1、Netty 有哪些核心組件?

 

  • Channel

基礎的 IO 操作,如綁定、連接、讀寫等都依賴於底層網絡傳輸所提供的原語,在 Java 的網絡編程中,基礎核心類是 Socket,而 Netty 的 Channel 提供了一組 API,極大地簡化了直接與 Socket 進行操作的複雜性,並且 Channel 是很多類的父類,如 EmbeddedChannel、LocalServerChannel、NioDatagramChannel、NioSctpChannel、NioSocketChannel 等。

  • EventLoop

EventLoop 定義了處理在連接過程中發生的事件的核心抽象。

說白了,EventLoop 的主要作用實際就是負責監聽網絡事件並調用事件處理器進行相關 IO 操作的處理。

那 Channel 和 EventLoop 直接有啥聯繫呢?

Channel 爲 Netty 網絡操作(讀寫等操作)抽象類,EventLoop 負責處理註冊到其上的 Channel 處理 IO 操作,兩者配合參與 IO 操作

  • ChannelFuture

由於 Netty 是異步非阻塞的,所有的 IO 操作也都爲異步的,我們不能立刻得到操作是否執行成功,因此 Netty 提供 ChannelFuture 接口,使用其 addListener() 方法註冊一個 ChannelFutureListener,當操作執行成功或者失敗時,監聽就會自動觸發返回結果。

並且,我們還可以通過 ChannelFuture 的 channel() 方法獲取關聯的Channel,甚至使用 sync() 方法讓異步的操作變成同步的。

  • ChannelHandler 和 ChannelPipeline

從應用開發者看來,ChannelHandler 是最重要的組件,其中存放用來處理進站和出站數據的用戶邏輯。ChannelHandler 的方法被網絡事件觸發,可以用於幾乎任何類型的操作,如將數據從一種格式轉換爲另一種格式或處理拋出的異常。如其子接口ChannelInboundHandler,接受進站的事件和數據以便被用戶定義的邏輯處理,或者當響應所連接的客戶端時刷新ChannelInboundHandler的數據。

ChannelPipeline爲ChannelHandler 鏈提供了一個容器並定義了用於沿着鏈傳播入站和出站事件流的 API。當創建 Channel 時,會自動創建一個附屬的 ChannelPipeline。

  • Bootstrap 和 ServerBootstrap

Netty 的引導類應用程序網絡層配置提供容器,其涉及將進程綁定到給定端口或連接一個進程到在指定主機上指定端口上運行的另一進程。引導類分爲客戶端引導 Bootstrap 和服務端引導 ServerBootstrap。

 

2、什麼是 EventLoop 和 EventLoopGroup?


EventLoopGroup 包含多個 EventLoop(每一個 EventLoop 通常內部包含一個線程),上面我們已經說了 EventLoop 的主要作用實際就是負責監聽網絡事件並調用事件處理器進行相關 I/O 操作的處理。

並且 EventLoop 處理的 I/O 事件都將在它專有的 Thread 上被處理,即 Thread 和 EventLoop 屬於 1 : 1 的關係,從而保證線程安全。

上圖是一個服務端對 EventLoopGroup 使用的大致模塊圖,其中 Boss EventloopGroup 用於接收連接,Worker EventloopGroup 用於具體的處理(消息的讀寫以及其他邏輯處理)。

 

 

 

 

從上圖可以看出:當客戶端通過 connect 方法連接服務端時,bossGroup 處理客戶端連接請求。當客戶端處理完成後,會將這個連接提交給 workerGroup 來處理,然後 workerGroup 負責處理其 IO 相關操作。

3、說說 Netty 的線程模型?

Netty 通過 Reactor 模型基於多路複用器接收並處理用戶請求,內部實現了兩個線程池,boss 線程池和 work 線程池,其中 boss 線程池的線程負責處理請求的 accept 事件,當接收到 accept 事件的請求時,把對應的 socket 封裝到一個 NioSocketChannel 中,並交給 work 線程池,其中 work 線程池負責請求的 read 和 write 事件,由對應的 Handler 處理。

單線程模型
所有 IO 操作都由一個線程完成,即多路複用、事件分發和處理都是在一個 Reactor 線程上完成的。既要接收客戶端的連接請求,向服務端發起連接,又要發送、讀取請求或應答、響應消息。一個 NIO 線程同時處理成百上千的鏈路,性能上無法支撐,速度慢,若線程進入死循環,整個程序不可用,對於高負載、高併發的應用場景不合適。

//1.eventGroup既用於處理客戶端連接,又負責具體的處理。 
EventLoopGroup eventGroup = new NioEventLoopGroup(1); 
//2.創建服務端啓動引導/輔助類:
ServerBootstrap ServerBootstrap b = new ServerBootstrap(); 
boobtstrap.group(eventGroup, eventGroup) 
//......

 


多線程模型
有一個 NIO 線程(Acceptor) 只負責監聽服務端,接收客戶端的 TCP 連接請求;NIO 線程池負責網絡 IO 的操作,即消息的讀取、解碼、編碼和發送;1 個 NIO 線程可以同時處理 N 條鏈路,但是 1 個鏈路只對應 1 個 NIO 線程,這是爲了防止發生併發操作問題。但在併發百萬客戶端連接或需要安全認證時,一個 Acceptor 線程可能會存在性能不足問題。

 

 

 

 

對於代碼:

// 1.bossGroup 用於接收連接,workerGroup 用於具體的處理
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try { 
//2.創建服務端啓動引導/輔助類:
ServerBootstrap ServerBootstrap b = new ServerBootstrap(); 
//3.給引導類配置兩大線程組,確定了線程模型 
b.group(bossGroup, workerGroup) 
//......
}

 

 

 

 

 



主從多線程模型
Acceptor 線程用於綁定監聽端口,接收客戶端連接,將 SocketChannel 從主線程池的 Reactor 線程的多路複用器上移除,重新註冊到 Sub 線程池的線程上,用於處理 IO 的讀寫等操作,從而保證主 Reactor 只負責接入認證、握手等操作。如果多線程模型無法滿足你的需求的時候,可以考慮使用主從多線程模型 。

 

 

 

 

// 1.bossGroup 用於接收連接,workerGroup 用於具體的處理
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try { 
//2.創建服務端啓動引導/輔助類:
ServerBootstrap ServerBootstrap b = new ServerBootstrap(); 
//3.給引導類配置兩大線程組,確定了線程模型 
b.group(bossGroup, workerGroup) 
//......
}

 

4、Netty 服務端的啓動過程?

先來看一段代碼實現:


// 1.bossGroup 用於接收連接,workerGroup 用於具體的處理
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//2.創建服務端啓動引導/輔助類:ServerBootstrap
ServerBootstrap b = new ServerBootstrap();
//3.給引導類配置兩大線程組,確定了線程模型
b.group(bossGroup, workerGroup) // (非必備)打印日誌
.handler(new LoggingHandler(LogLevel.INFO)) // 4.指定 IO 模型
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
//5.可以自定義客戶端消息的業務處理邏輯
p.addLast(new HelloServerHandler());
}
});
// 6.綁定端口,調用 sync 方法阻塞知道綁定完成
ChannelFuture f = b.bind(port).sync();
// 7.阻塞等待直到服務器Channel關閉(closeFuture()方法獲取Channel 的CloseFuture對象,然後調用sync()方法)
f.channel().closeFuture().sync();
} finally {
//8.優雅關閉相關線程組資源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}

 

 

三   具體實現

1、Netty 的無鎖化體現在哪裏?


Netty 採用了串行無鎖化設計在 IO 線程內部進行串行操作,避免多線程競爭導致的性能下降。表面上看,串行化設計似乎 CPU 利用率不高,併發程度不夠。但是,通過調整 NIO 線程池的線程參數,可以同時啓動多個串行化的線程並行運行,這種局部無鎖化的串行線程設計相比一個隊列-多個工作線程模型性能更優。

 

 

 

Netty 的 NioEventLoop 讀取到消息後,直接調用 ChannelPipeline 的 fireChannelRead(Object msg),只要用戶不主動切換線程,一直會由 NioEventLoop 調用到用戶的 handler,期間不進行線程切換,這種串行化處理方式避免了多線程操作導致的鎖競爭,從性能角度看是最優的。

2、如何解決 JDK epoll 空輪詢問題?


這個 BUG 是指 Java 的 NIO 在 Linux 下進行 selector.select() 時,本來如果輪詢的結果爲空並且不調用 wakeup 方法的話,這個 selector.select() 應該是一直阻塞的,但是 Java 卻會打破阻塞,繼續執行,導致程序無限空轉,造成 CPU 使用率 100%。(這個問題只存在 Linux 是因爲 Linux 的 NIO 是基於 epoll 實現的,而 Java 實現的 epoll 存在 BUG,windows 下 NIO 基於 poll 就不存在此問題)

Netty 的解決方案:

爲 Selector 的 select 操作設置超時時間,同時定義可以跳出阻塞的四種情況

  • 有事件發生
  • wakeup
  • 超時
  • 空輪詢 BUG

而前兩種返回值不爲 0,可以跳出循環,超時有時間戳記錄,所以每次空輪詢,有專門的計數器進行 +1,如果空輪詢的次數超過了 512 次(默認),就認爲其觸發了空輪詢 BUG。

當觸發 BUG 後,Netty 直接重建一個 Selector,將原來的 Channel 重新註冊到新的 Selector 上,並將舊的 Selector 關掉。

3、什麼是拆包和粘包?


TCP 是一個面向流的傳輸協議,所謂流,就是沒有界限的一串數據。TCP 底層並不瞭解上層業務數據的具體含義,它會根據 TCP 緩衝區的實際情況進行包的劃分,所以在業務上認爲,一個完整的包可能會被 TCP 拆分成多個包進行發送,也有可能把多個小的包封裝成一個大的數據包發送,這就是所謂的 TCP 粘包和拆包問題。

粘包和拆包是 TCP 網絡編程中不可避免的,無論是服務端還是客戶端,當我們讀取或者發送消息的時候,都需要考慮 TCP 底層的粘包/拆包機制。

 

 

 

數據從發送方到接收方需要經過操作系統的緩衝區,而造成粘包和拆包的主要原因就在這個緩衝區上。粘包可以理解爲緩衝區數據堆積,導致多個請求數據粘在一起,而拆包可以理解爲發送的數據大於緩衝區,進行拆分處理。

詳細來說,造成粘包和拆包的原因主要有以下三個:

1)應用程序 write 寫入的字節大小大於套接口發送緩衝區大小;

2)進行 MSS 大小的 TCP 分段;

3)以太網幀的 payload 大於 MTU 進行 IP 分片。

4、拆包粘包的解決方案?


由於底層的 TCP 無法理解上層的業務數據,所以在底層是無法保證數據包不被拆分和重組的,這個問題只能通過上層的應用協議棧設計來解決,根據業界的主流協議可以歸納出以下解決方案:

1)消息長度固定,累計讀取到長度和爲定長LEN的報文後,就認爲讀取到了一個完整的信息。

2)將特殊的分隔符作爲消息的結束標誌,如回車換行符。

3)通過在消息頭中定義長度字段來標識消息的總長度。

5、Netty 如何解決拆包粘包?


相比粘包,拆包問題比較簡單,用戶可以自己定義自己的編碼器進行處理,Netty 並沒有提供相應的組件。對於粘包的問題,代碼比較繁瑣,Netty 提供了 4 種解碼器來解決,分別如下:

  • 固定長度的拆包器(FixedLengthFrameDecoder),每個應用層數據包的都拆分成都是固定長度的大小;
  • 行拆包器(LineBasedFrameDecoder),每個應用層數據包都以換行符作爲分隔符,進行分割拆分;
  • 分隔符拆包器(DelimiterBasedFrameDecoder),每個應用層數據包,都通過自定義的分隔符,進行分割拆分;
  • 基於數據包長度的拆包器(LengthFieldBasedFrameDecoder),將應用層數據包的長度,作爲接收端應用層數據包的拆分依據。按照應用層數據包的大小,拆包。這個拆包器,有一個要求,就是應用層協議中包含數據包的長度。

 

6、Netty 零拷貝體現在哪裏?


Zero-copy 就是在操作數據時, 不需要將數據 buffer從 一個內存區域拷貝到另一個內存區域。 少了一次內存的拷貝,CPU 效率就得到的提升。

  • 接收和發送 ByteBuffer 採用 DIRECT BUFFERS,使用堆外直接內存進行 Socket 讀寫,不需要進行字節緩衝區的二次拷貝;
  • 提供了組合 Buffer 對象,可以聚合多個 ByteBuffer 對象,用戶可以像操作一個 Buffer 那樣方便的對組合 Buffer 進行操作;
  • 文件傳輸採用了 transferTo 方法,它可以直接將文件緩衝區的數據發送到目標 Channel,避免了傳統通過循環 write 方式導致的內存拷貝問題。

和操作系統上的零拷貝的區別?

  • Netty 的 Zero-copy 完全是在用戶態(Java 應用層)的, 更多的偏向於優化數據操作。
  • 而在 OS 層面上的 Zero-copy 通常指避免在用戶態(User-space)與內核態(Kernel-space)之間來回拷貝數據。

7、TCP 的長連接和短連接?


我們知道 TCP 在進行讀寫之前,server 與 client 之間必須提前建立一個連接。建立連接的過程,需要我們常說的三次握手,釋放/關閉連接的話需要四次揮手。這個過程是比較消耗網絡資源並且有時間延遲的

所謂,短連接說的就是 server 端 與 client 端建立連接之後,讀寫完成之後就關閉掉連接,如果下一次再要互相發送消息,就要重新連接。短連接的有點很明顯,就是管理和實現都比較簡單,缺點也很明顯,每一次的讀寫都要建立連接必然會帶來大量網絡資源的消耗,並且連接的建立也需要耗費時間。

長連接說的就是 client 向 server 雙方建立連接之後,即使 client 與 server 完成一次讀寫,它們之間的連接並不會主動關閉,後續的讀寫操作會繼續使用這個連接。長連接的可以省去較多的 TCP 建立和關閉的操作,降低對網絡資源的依賴,節約時間。對於頻繁請求資源的客戶來說,非常適用長連接。

8、Netty 長連接、心跳機制瞭解麼?


在 TCP 保持長連接的過程中,可能會出現斷網等網絡異常出現,異常發生的時候, client 與 server 之間如果沒有交互的話,它們是無法發現對方已經掉線的。爲了解決這個問題, 我們就需要引入心跳機制

心跳機制的工作原理是: 在 client 與 server 之間在一定時間內沒有數據交互(即處於 idle 狀態)時, 客戶端或服務器就會發送一個特殊的數據包給對方, 當接收方收到這個數據報文後, 也立即發送一個特殊的數據報文, 迴應發送方, 此即一個 PING-PONG 交互。所以, 當某一端收到心跳消息後, 就知道了對方仍然在線, 這就確保 TCP 連接的有效性。

TCP 實際上自帶的就有長連接選項,本身是也有心跳包機制,也就是 TCP 的選項:SO_KEEPALIVE。但 TCP 協議層面的長連接靈活性不夠,所以,一般情況下我們都是在應用層協議上實現自定義心跳機制的,也就是在 Netty 層面通過編碼實現。通過 Netty 實現心跳機制的話,核心類是 IdleStateHandler 。

9、說說 Netty 的對象池技術?


對象池其實就是緩存一些對象從而避免大量創建同一個類型的對象,類似線程池的概念。對象池緩存了一些已經創建好的對象,避免需要時才創建對象,同時限制了實例的個數。池化技術最終要的就是重複的使用池內已經創建的對象。從上面的內容就可以看出對象池適用於以下幾個場景:

  • 創建對象的開銷大;
  • 會創建大量的實例;
  • 限制一些資源的使用。

Netty 自己實現了一套輕量級的對象池。在 Netty 中,通常會有多個 IO 線程獨立工作(基於 NioEventLoop 實現)。每個 IO 線程輪詢單獨的 Selector 實例來檢索 IO 事件,並在 IO 來臨時開始處理。最常見的 IO 操作就是讀寫,具體到 NIO 就是從內核緩衝區拷貝數據到用戶緩衝區或者從用戶緩衝區拷貝數據到內核緩衝區。這裏會涉及到大量的創建和回收 Buffer, Netty 對 Buffer 進行了池化從而降低系統開銷。

ref:https://www.jianshu.com/p/3bfe0de2b022

10 有哪些序列化協議?


序列化(編碼)是將對象序列化爲二進制形式(字節數組),主要用於網絡傳輸、數據持久化等;

而反序列化(解碼)則是將從網絡、磁盤等讀取的字節數組還原成原始對象,主要用於網絡傳輸對象的解碼,以便完成遠程調用。

影響序列化性能的關鍵因素:

  • 序列化後的碼流大小(網絡帶寬的佔用)、
  • 序列化的性能(CPU資源佔用);
  • 是否支持跨語言(異構系統的對接和開發語言切換)。

 

目前幾種主流協議

  • Java 默認提供的序列化
    • 無法跨語言、序列化後的碼流太大、序列化的性能差。

 

  • XML
    • 優點是人機可讀性好,可指定元素或特性的名稱。
    • 缺點:序列化數據只包含數據本身以及類的結構,不包括類型標識和程序集信息;只能序列化公共屬性和字段;不能序列化方法;文件龐大,文件格式複雜,傳輸佔帶寬。
    • 適用場景:當做配置文件存儲數據,實時數據轉換。

 

  • JSON
    • 是一種輕量級的數據交換格式,
    • 優點:兼容性高、數據格式比較簡單,易於讀寫、序列化後數據較小,可擴展性好,兼容性好、與XML相比,其協議比較簡單,解析速度比較快。
    • 缺點:數據的描述性比XML差、不適合性能要求爲ms級別的情況、額外空間開銷比較大。
    • 適用場景(可替代XML):跨防火牆訪問、可調式性要求高、基於Web browser的Ajax請求、傳輸數據量相對小,實時性要求相對低(例如秒級別)的服務。

 

  • Fastjson
    • 採用一種“假定有序快速匹配”的算法。
    • 優點:接口簡單易用、目前java語言中最快的json庫。
    • 缺點:過於注重快,而偏離了“標準”及功能性、代碼質量不高,文檔不全。
    • 適用場景:協議交互、Web輸出、Android客戶端。

 

  • Thrift
    • 不僅是序列化協議,還是一個RPC框架。
    • 優點:序列化後的體積小, 速度快、支持多種語言和豐富的數據類型、對於數據字段的增刪具有較強的兼容性、支持二進制壓縮編碼。
    • 缺點:使用者較少、跨防火牆訪問時,不安全、不具有可讀性,調試代碼時相對困難、不能與其他傳輸層協議共同使用(例如HTTP)、無法支持向持久層直接讀寫數據,即不適合做數據持久化序列化協議。
    • 適用場景:分佈式系統的RPC解決方案。

 

  • Avro
    • Hadoop的一個子項目,解決了JSON的冗長和沒有IDL的問題。
    • 優點:支持豐富的數據類型、簡單的動態語言結合功能、具有自我描述屬性、提高了數據解析速度、快速可壓縮的二進制數據形式、可以實現遠程過程調用RPC、支持跨編程語言實現。
    • 缺點:對於習慣於靜態類型語言的用戶不直觀。
    • 適用場景:在Hadoop中做Hive、Pig和MapReduce的持久化數據格式。

 

  • Protobuf
    • 將數據結構以.proto文件進行描述,通過代碼生成工具可以生成對應數據結構的POJO對象和Protobuf相關的方法和屬性。
    • 優點:序列化後碼流小,性能高、結構化數據存儲格式(XML JSON等)、通過標識字段的順序,可以實現協議的前向兼容、結構化的文檔更容易管理和維護。
    • 缺點:需要依賴於工具生成代碼、支持的語言相對較少,官方只支持Java 、C++ 、python。
    • 適用場景:對性能要求高的RPC調用、具有良好的跨防火牆的訪問屬性、適合應用層對象的持久化。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章