RPC(Remote Procedure Call,遠程過程調用)是一種計算機通訊協議,容許調用不一樣進程空間的程序。RPC 的客戶端和服務器能夠在一臺機器上,也能夠在不一樣的機器上。程序員使用時,就像調用本地程序同樣,無需關注內部的實現細節。html
不一樣的應用程序之間的通訊方式有不少,好比瀏覽器和服務器之間普遍使用的基於 HTTP 協議的 Restful API。與 RPC 相比,Restful API 有相對統一的標準,於是更通用,兼容性更好,支持不一樣的語言。HTTP 協議是基於文本的,通常具有更好的可讀性。可是缺點也很明顯:程序員
RPC 框架須要解決什麼問題?或者咱們換一個問題,爲何須要 RPC 框架?golang
咱們能夠想象下兩臺機器上,兩個應用程序之間須要通訊,那麼首先,須要肯定採用的傳輸協議是什麼?若是這個兩個應用程序位於不一樣的機器,那麼通常會選擇 TCP 協議或者 HTTP 協議;那若是兩個應用程序位於相同的機器,也能夠選擇 Unix Socket 協議。傳輸協議肯定以後,還須要肯定報文的編碼格式,好比採用最經常使用的 JSON 或者 XML,那若是報文比較大,還可能會選擇 protobuf 等其餘的編碼方式,甚至編碼以後,再進行壓縮。接收端獲取報文則須要相反的過程,先解壓再解碼。面試
解決了傳輸協議和報文編碼的問題,接下來還須要解決一系列的可用性問題,例如,鏈接超時了怎麼辦?是否支持異步請求和併發?瀏覽器
若是服務端的實例不少,客戶端並不關心這些實例的地址和部署位置,只關心本身可否獲取到期待的結果,那就引出了註冊中心(registry)和負載均衡(load balance)的問題。簡單地說,即客戶端和服務端互相不感知對方的存在,服務端啓動時將本身註冊到註冊中心,客戶端調用時,從註冊中心獲取到全部可用的實例,選擇一個來調用。這樣服務端和客戶端只須要感知註冊中心的存在就夠了。註冊中心一般還須要實現服務動態添加、刪除,使用心跳確保服務處於可用狀態等功能。服務器
再進一步,假設服務端是不一樣的團隊提供的,若是沒有統一的 RPC 框架,各個團隊的服務提供方就須要各自實現一套消息編解碼、鏈接池、收發線程、超時處理等「業務以外」的重複技術勞動,形成總體的低效。所以,「業務以外」的這部分公共的能力,便是 RPC 框架所須要具有的能力。併發
Go 語言普遍地應用於雲計算和微服務,成熟的 RPC 框架和微服務框架汗牛充棟。grpc
、rpcx
、go-micro
等都是很是成熟的框架。通常而言,RPC 是微服務框架的一個子集,微服務框架能夠本身實現 RPC 部分,固然,也能夠選擇不一樣的 RPC 框架做爲通訊基座。負載均衡
考慮性能和功能,上述成熟的框架代碼量都比較龐大,並且一般和第三方庫,例如 protobuf
、etcd
、zookeeper
等有比較深的耦合,難以直觀地窺視框架的本質。GeeRPC 的目的是以最少的代碼,實現 RPC 框架中最爲重要的部分,幫助你們理解 RPC 框架在設計時須要考慮什麼。代碼簡潔是第一位的,功能是第二位的。框架
所以,GeeRPC 選擇從零實現 Go 語言官方的標準庫 net/rpc
,並在此基礎上,新增了協議交換(protocol exchange)、註冊中心(registry)、服務發現(service discovery)、負載均衡(load balance)、超時處理(timeout processing)等特性。分七天完成,最終代碼約 1000 行。異步
原文地址: 7天用Go從零實現RPC框架GeeRPC - 極客兔兔
關注知乎: 極客兔兔
關注微博: @極客兔兔