為什么說要搞定微服務架構,先搞定 RPC 框架?
第一章聊了【 “為什么要進行服務化,服務化究竟解決什么問題” 】
第二章聊了【 “微服務的服務粒度選型” 】
今天開始聊一些 微服務的實踐 ,第一塊, RPC 框架的原理及實踐 ,為什么說要搞定微服務架構,先搞定RPC框架呢?
一、需求緣起
服務化的一個好處就是,不限定服務的提供方使用什么技術選型,能夠實現大公司跨團隊的技術解耦 ,如下圖:
服務 A 是歐洲團隊提供服務,歐洲團隊的技術背景是 Java ,可以用 Java 實現服務;
服務 B 是美洲團隊提供服務,可以用 C++ 實現服務;
服務 C 是中國團隊提供服務,可以用 Go 實現服務;
服務的上游調用方,按照接口、協議即可完成對遠端服務的調用。
但實際上, 99.9% 的公司的團隊規模有限,技術團隊人數也有限,基本是使用同一套技術體系來調用和提供服務 的:
這樣的話, 如果沒有統一的服務框架, RPC 框架 , 各個團隊的服務提供方就需要各自實現一套序列化、反序列化、網絡框架、連接池、收發線程、超時處理、狀態機等“業務之外”的重復技術勞動 ,造成整體的低效。所以, 統一 RPC 框架 把上述“業務之外”的技術勞動統一處理, 是服務化首要解決的問題 。
在達成【“使用統一的 RPC 框架”是正確的道路】這個一致的前提下,本文期望用簡單通俗的言語簡述一下一個通用 RPC 框架的技術點與實現。
二、 RPC 背景與過程
什么是 RPC ( Remote Procedure Call Protocol ),遠程過程調用?
先來看下什么是本地函數調用,當我們寫下:
int result = Add(1, 2);
這段代碼的時候,我們知道,我們傳入了 1 , 2 兩個入參數,調用了本地代碼段中的一個 Add 函數,得到了 result 出參。此時, 傳入數據,傳出數據,代碼段在同一個進程空間里,這是本地函數調用 。
那有沒有辦法,我們能夠調用一個跨進程(所以叫 “ 遠程 ” ,典型的,這個進程部署在另一臺服務器上)的函數呢 ?
最容易想到的, 兩個進程約定一個協議格式,使用 Socket 通信,來傳輸【入參】【調用哪個函數】【出參】 。
假設請求報文協議是一個 11 字節的字節流:
( 1 )前 3 個字節填入函數名
( 2 )中間 4 個字節填入第一個參數
( 3 )末尾 4 個字節填入第二個參數
同時可以設計響應報文協議是一個 4 字節的字節流:
即處理結果。
調用方的代碼可能變為:
request = MakePacket(“add”, 1, 2);
SendRequest_ToService_B(request);
response = RecieveRespnse_FromService_B();
int result = unMakePacket(respnse);
簡單解釋一下:
( 1 )講傳入參數變為字節流
( 2 )將字節流發給服務 B
( 3 )從服務 B 接受返回字節流
( 4 )將返回字節流變為傳出參數
服務方的代碼可能變為:
request = RecieveRequest();
args/function = unMakePacket(request);
result = Add(1, 2);
response = MakePacket(result);
SendResponse(response);
這個過程也很好理解:
( 1 )服務端收到字節流
( 2 )將字節流轉為函數名與參數
( 3 )本地調用函數得到結果
( 4 )將結果轉變為字節流
( 5 )將字節流發送給調用方
這個過程用一張圖描述如上,調用方與服務方的處理步驟都是非常清晰的。 這個過程存在最大的問題是什么呢?
回答:調用方太麻煩了,每次都要關注很多底層細節
( 1 )入參到字節流的轉化,即序列化應用層協議細節
( 2 ) socket 發送,即網絡傳輸協議細節
( 3 ) socket 接受
( 4 )字節流到出參的轉化,即反序列化應用層協議細節
能不能調用層不關注這個細節呢?
回答:可以, RPC 框架就是解決這個問題的,它能夠讓調用方“像調用本地函數一樣調用遠端的函數(服務)” 。
三、 RPC 框架職責
通過上面的討論, RPC 框架要向調用方屏蔽各種復雜性,要向服務提供方也屏蔽各類復雜性 :
( 1 )調用方感覺就像調用本地函數一樣
( 2 )服務提供方感覺就像實現一個本地函數一樣來實現服務
所以整個 RPC 框架又分為 client 部分與 server 部分,負責把整個非( 1 )( 2 )的各類復雜性屏蔽,這些復雜性就是 RPC 框架的職責。
再細化一些, client 端又包含:序列化、反序列化、連接池管理、負載均衡、故障轉移、隊列管理,超時管理、異步管理等等等等職責。
server 端包含:服務端組件、服務端收發包隊列、 io 線程、工作線程、序列化反序列化、上下文管理器、超時管理、異步回調等等等等職責。
however ,因為篇幅有限,這些細節不做深入展開。
四、結論
( 1 ) RPC 框架是架構微服務化的首要基礎組件 ,它能大大降低架構微服務化的成本,提高調用方與服務提供方的研發效率,屏蔽跨進程調用函數(服務)的各類復雜細節
( 2 ) RPC 框架的 職責 是: 讓調用方感覺就像調用本地函數一樣調用遠端函數、讓服務提供方感覺就像實現一個本地函數一樣來實現服務
來自:http://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651959553&idx=1&sn=c1084e91875721c5f6baf544450afa38&scene=0