技術帖 | dubbo原始碼分析 -- 遠端通訊 netty
dubbo 底層通訊選擇了 netty 這個 nio 框架做為預設的網路通訊框架並且通過自定義協議進行通訊。dubbo 支援以下網路通訊框架:
Netty(預設)
Mina
Grizz ly
Netty是什麼?
①本質:由JBOSS提供的一個java開源框架(一個jar包)
②目的:快速開發高效能、高可靠性的網路伺服器和客戶端程式
③優點:提供非同步的、事件驅動的網路應用程式框架和工具
通俗來說。一個好使的處理socket的框架。
高併發
Netty是一款基於NIO(Nonblocking I/O,非阻塞IO)開發的網路通訊框架,對比於BIO(Blocking I/O,阻塞IO),他的併發效能得到了很大提高。
BIO
NIO
對比兩張圖可以看出,右圖中出現了selector,這也正是NIO的單執行緒處理連線的數量比BIO高出很多的原因。
當一個連線建立之後,他有兩個步驟要做,第一步是接收完客戶端發過來的全部資料,第二步是服務端處理完請求業務之後返回response給客戶端。NIO和BIO的區別主要是在第一步。
在BIO中,等待客戶端發資料這個過程是阻塞的,這樣就造成了一個執行緒只能處理一個請求的情況,而機器能支援的最大執行緒數是有限的,這就是為什麼BIO不能支援高併發的原因。
而NIO中,當一個Socket建立好之後,Thread並不會阻塞去接受這個Socket,而是將這個請求交給Selector,Selector會不斷的去遍歷所有的Socket,一旦有一個Socket建立完成,他會通知Thread,然後Thread處理完資料再返回給客戶端——這個過程是阻塞的
BIO,同步阻塞IO,阻塞整個步驟,如果連線少,他的延遲是最低的,因為一個執行緒只處理一個連線,適用於少連線且延遲低的場景,比如說資料庫連線。
NIO,同步非阻塞IO,阻塞業務處理但不阻塞資料接收,適用於高併發且處理簡單的場景,比如聊天軟體。
傳輸快
Netty的傳輸快其實也是依賴了NIO的一個特性——零拷貝。我們知道,Java的記憶體有堆記憶體、棧記憶體和字串常量池等等,其中堆記憶體是佔用記憶體空間最大的一塊,也是Java物件存放的地方,一般我們的資料如果需要從IO讀取到堆記憶體,中間需要經過Socket緩衝區,也就是說一個數據會被拷貝兩次才能到達他的的終點,如果資料量大,就會造成不必要的資源浪費。
核心元件
1.Channel
資料傳輸流,與channel相關的概念有以下四個↓
一張圖讓你瞭解netty裡面的Channel。
2.ByteBuf
ByteBuf是一個儲存位元組的容器,最大特點就是使用方便,它既有自己的讀索引和寫索引,方便你對整段位元組快取進行讀寫,也支援get/set。
3.EventLoop
EventLoop 是 Netty 的核心概念, netty 裡面的網路程式設計處理都是基於事件回撥。下面的圖說明了 Channel、EventLoop、Thread 以及 EventLoopGroup 之間的關係。
它們的關係是:
一個 EventLoopGroup 包含一個或者多個 EventLoop;
一個 EventLoop 在它的生命週期內只和一個 Thread 繫結;
所有的 EventLoop 處理的 I/O 事件都將在它專門的 Thread 被處理;
一個 Channel 在它的生命週期內只註冊於一個 EventLoop;
一個 EventLoop 可能會被分配一個或者多個 Channel。
Netty 這樣的設計,一個操作 I/O 的 Channel 都會由相同的 Thread 執行的,這樣就能夠消除執行緒之間的同步。所以 Netty 內部是通過回撥來處理事件。當一個回撥被觸發時相關的事件。
歡迎工作一到十年的Java工程師朋友們加入Java進階高階架構:828545509
本群提供免費的學習指導 架構資料 以及免費的解答
不懂得問題都可以在本群提出來 之後還會有職業生涯規劃以及面試指導