『網際網路架構』軟體架構-RPC網路傳輸原理與實現(45)
回顧下:普通RPC框架需要做的:服務的註冊,發現,暴露。服務註冊包括:呼叫模組(負載均衡,容錯,透明)。RPC協議包括(序列化,編碼,傳輸),其實透明化的遠端呼叫。RPC報文的格式:請求行,請求頭和請求體。RPC協議相比HTTP要更加精簡,傳輸的量要更少。今天主要說說傳輸這塊,其實也是最複雜的,說這個意義,感覺只是使用dubbo,其實對開發者的意義不是很大,大家不需要了解底層的業務傳輸,但是如果要設計一個訊息伺服器,這可是一般的開發人員可以搞定的。必須有過一定的經驗,參考過別人的一個遠端實現。瞭解了這些對dubbo的效能調優和配置有更深層的認識,而不是dubbo,api文件裡面的一些配置
底層看了,框架在變化,不變的永遠是底層。底層通訊服務用到與:android端、ios端的推送資訊。與特殊的裝置進行網路的通訊傳輸。
(一)Dubbo基於Netty網路傳輸的實現
一個RPC協議實現由 通訊模組、報文編解碼模組、序列化模組組成,其中通訊模組就是RPC網路傳輸的實現。其穩定性和效能就直接影響了RPC服務的穩定和效能。如何保證傳輸模組的穩定和效能呢?
如果想搞定傳輸模組的穩定和效能,必須要先了解RPC協議的組成,一直強調模組的拆分,模組內在進行模組的拆分,也就是一點一點的進行組成,像積木一樣。
1.IO模型:
RPC框架必然一定:不是NIO就是AIO。
- BIO 同阻塞(一夫一妻制)
執行緒發起IO請求,不管核心是否準備好IO操作,從發起請求起,執行緒一直阻塞,直到操作完成。一個連線一個執行緒。
- NIO 同步非阻塞(一夫多妻制)
執行緒發起IO請求,立即返回;核心在做好IO操作的準備之後,通過呼叫註冊的回撥函式通知執行緒做IO操作,執行緒開始阻塞,直到操作完成。一個請求一個執行緒。
- AIO 非同步非阻塞
執行緒發起IO請求,立即返回;記憶體做好IO操作的準備之後,做IO操作,直到操作完成或者失敗,通過呼叫註冊的回撥函式通知執行緒做IO操作完成或者失敗。一個有效請求一個執行緒。
2.連線模型
網路傳輸模型:底層都是tcp連線。RPC一般使用長連線。
- 長連線
當客戶端和服務端建立連線後,就連線了一個tcp連線。用了之後不會釋放一直儲存,一直進行通訊。http是長連線。用完了才關閉,
http的keeplive 是多長時間主動的斷開。
tcp的keeplive 是多久完成一次狀態的檢測,是保護連線。
長連線不適合傳輸比較大的欄位。大檔案把所有的都站住了,其他人過來沒的玩了。
- 短連線
當連線完畢後,就釋放掉連線。
大檔案適合短連線。所有有IO執行緒。
3.執行緒分類
– IO執行緒
IO雖然是負責流的讀寫,其實耗時最多的就是業務上邊的。編碼和解碼屬於io執行緒。
- 服務端業務執行緒
> tomcat 或者dubbo 設定執行緒池的執行緒,其實就是在設定的業務執行緒。 - 客戶端排程執行緒
>類例項化遠端的類裡面的方法,就是排程執行緒完成的。但是傳輸的過程都是通過的io執行緒。 - 客戶端結果exchange執行緒
結果傳送給排程執行緒。
- 保活心跳執行緒
保證連線一直是長連線。
- 重連執行緒
>掛掉了重新連回來。
4.執行緒池模型
所有的執行緒都會涉及到執行緒池的概念。
– 固定數量執行緒池
– 快取執行緒池
– 有限執行緒池
(二)長連線的建立與維護
Dubbo 長連線實現與配置
* 初始連線
引用服務|增加提供者==>獲取連線===>是否獲取共享連線==>建立連線客戶端==>開啟心跳檢測狀態檢查定時任務===>開啟連線狀態檢測
原始碼見:com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol#getClients
- 心跳傳送
在建立一個連線客戶端同時也會建立一個心跳客戶端,客戶端預設基於60秒傳送一次心跳來保持連線的存活,可通過 heartbeat 設定。
原始碼見:com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeClient#startHeatbeatTimer
- 斷線重連
每建立一個客戶端連線都會啟動一個定時任務每兩秒中檢測一次當前連線狀態,如果斷線則自動重連。
原始碼見:com.alibaba.dubbo.remoting.transport.AbstractClient#initConnectStatusCheckCommand
- 連線銷燬:
基於註冊中心通知,服務端斷開後銷燬
原始碼見:com.alibaba.dubbo.remoting.transport.AbstractClient#close()
(三)通訊執行緒協作流程
- Dubbo 傳輸協作執行緒
1.客戶端排程執行緒:用於發起遠端方法呼叫的執行緒。
2.客戶端結果Exchange執行緒:當遠端方法返回response後由該執行緒填充至指定ResponseFuture,並叫醒等待的排程執行緒。
3.客戶端IO執行緒:由傳輸框架實現,用於request 訊息流傳送、response 訊息流讀取與解碼等操作。
4.服務端IO執行緒:由傳輸框架實現,用於request訊息流讀取與解碼 和response編碼與傳送。
5.業務執行執行緒:服務端具體執行業務方法的執行緒 -
客戶端執行緒協作流程
1.排程執行緒
– 呼叫遠端方法
– 對request 進行協議編碼
– 傳送request 訊息至IO執行緒
– 等待結果的獲取
2.IO執行緒
– 讀取response流
– response 解碼
– 提交Exchange 任務
3.Exchange執行緒
– 填寫response值 至 ResponseFuture
– 喚醒排程執行緒,通知其獲取結果
- 服務端執行緒協作
1.IO執行緒:
– request 流讀取
– request 解碼
– 提交業務處理任務
2.業務執行緒:
– 業務方法執行
– response 解碼
– 回寫結果至channel
-
執行緒池
1.fixed:固定執行緒池,此執行緒池啟動時即建立固定大小的執行緒數,不做任何伸縮。
2.cached:快取執行緒池,此執行緒池可伸縮,執行緒空閒一分鐘後回收,新請求重新建立執行緒。
3.Limited:有限執行緒池,此執行緒池一直增長,直到上限,增長後不收縮。
PS:上邊的如果能搞明白,不是大神,也一隻腳踏進了大神的行列。
已是最新文章