什麼是RPC框架,主流的RPC框架有哪些,Golang中如何實現RPC服務
1. RPC協定簡介
1.1 什麼是RPC協議
- RPC又叫遠端過程呼叫(Remote Procedure Call,RPC)是一個電腦通訊協議
- RPC是一種使程式能夠在不同位址空間中執行子程序或服務的協定。透過RPC,程式可以像呼叫本地函數一樣呼叫遠端服務,從而隱藏了網路通訊的複雜性。
- RPC協定允許一台電腦的程式呼叫另一台電腦的子程式。
1.2 為什麼需要RPC協議
- 分散式系統支援:在分散式應用中,服務可能運行在不同的機器上,RPC簡化了它們之間的通訊。
- 簡化開發:開發者可以專注於業務邏輯,而無需處理底層網路細節。
- 模組化:允許將功能分散到多個服務中,方便維護和擴展。
1.3 RPC的優缺點
優點
- 透明性:呼叫遠端服務的方式與呼叫本機服務類似,開發者無需關心底層實作。
- 跨平台支援:不同系統和程式語言之間可以透過RPC進行通訊。
- 易於擴展:可以輕鬆新增新的服務,而不影響現有服務。
缺點
- 效能開銷:網路延遲和資料序列化/反序列化會增加回應時間。
- 故障處理複雜度:網路問題、服務宕機等情況會導致呼叫失敗,需要額外處理。
- 偵錯困難:遠端呼叫的錯誤比本地呼叫更難排查。
1.4 RPC協議的特點
- 序列化:資料在傳輸前需要序列化為位元組流,以便於在網路上傳輸,常用的格式包括JSON、XML、Protocol Buffers等。
- 同步與非同步:RPC可以是同步的(等待呼叫結果)或非同步的(立即返回,不等待結果)。
- 狀態管理:RPC呼叫通常是無狀態的,但某些實作可以支援會話狀態。
- 安全性:透過加密、認證等方式確保資料在傳輸過程中的安全性。
2. RPC框架
2.1 Dubbo
- 簡介:Dubbo是Java開發的一個流行的RPC框架,廣泛應用於Java專案中,整合了大多數服務治理方面的一些元件,支援服務治理,多種序列化協議,支援多種註冊中心,自帶服務管理中心,缺點是早期不支援跨語言通信,主要應用於Java專案之中。目前最新版本version3.3,已經支援多種語言SDK。
- 專案文件:https://cn.dubbo.apache.org/zh-cn/overview/
- Github位址:https://github.com/apache/dubbo/
2.2 Motan
- 簡介:Motan和Dubbo一樣也是Java開發的一個流行的RPC框架,廣泛應用於Java專案之中,和Dubbo框架一樣,早期不支援跨語言特性,後續版本增加了多語言版本,支援服務治理,多種序列化協議,支援多種註冊中心,自備服務管理中心,主要應用於Java專案之中。
- 官方文檔:https://github.com/weibocom/motan/wiki/zh_overview
- Github網址:https://github.com/weibocom/motan
2.3 Thrift
- 簡介:Thrift是一個跨語言輕量級RPC框架,最初是由Facebook開發維護,目前是由Apache開源維護,只支援Thrift協議,框架本身沒有實現服務治理和註冊元件,需要開發者自行整合。
- 官方地址:https://thrift.apache.org/
- Github位址:https://github.com/apache/thrift
2.4 Grpc
- 簡介:Grpc框架是由google開發開源,是一款語言中立、平台中立、開源的遠端過程呼叫系統,支援多語言,Grpc預設使用protocol buffers,是應用程式最廣泛的RPC框架,目前主流的應用程式大都支持和整合了Grpc服務接口,我們在實際開發和使用過程中一般是先定義proto文件,透過protoc來自動建立Grpc服務端。
- 官方地址:https://grpc.io/docs/
- Github位址:https://github.com/grpc/grpc
2.5 Rpcx
- 簡介:Rpcx是由國人鳥窩開發維護的一個高性能Rpc框架,主要特點以簡單易用,根據文檔步驟可以很輕易的集成在自己的項目中,高性能,跨平台,多語言支持,框架層面集成了服務發現,服務治理相關功能。
- 官方地址:https://rpcx.io/
- Github位址:https://github.com/smallnest/rpcx
3. Golang中實現Rpc服務
在Golang中實現Rpc服務非常簡單,Golang官方以及一些第三方函式庫都提供了Rpc服務實作方式,接下來我們以Golang官方提供的net/rpc
函式庫來簡單的實作一個Golang的Rpc服務。
3.1 net/rpc庫說明
- 序列化協議:
net/rpc
預設以encoding/gob
進行資料序列化,Golang獨有序列化協議,其他開發語言暫不支持,因此以net/rpc
庫開發的Rpc
伺服器,支援Golang語言自己內部呼叫。 - 其他序列化協定:為了多語言通信,GOlang官方在
net/rpc
包下提供了net/rpc/jsonrpc
庫,支持以json
的形式進行資料序列化,以實現Rpc
服務跨語言呼叫。
3.2 基於net/rpc庫實現Rpc服務
3.2.1 Rpc服務端
package main import ( "log" "net/http" "net/rpc" ) // Golang基於net/rpc函式庫實作Rpc服務type Request struct { M int N int } type Server struct{} func (s *Server) Multiply (r Request, res *int) error { *res = rM * rN return nil } // main函式func main() { // 服務註冊serv := new(Server) // 註冊serv服務if err := rpc. Register(serv); err != nil { log.Panicf("register server error, %s\n", err) return } // 將serv服務綁定到Http服務上rpc.HandleHTTP() // 監聽HTTP服務if err := http.ListenAndServe("127.0.0.1:8081", nil); err != nil { log.Panicf("ListenAndServe error, %s\n", err) return } }
3.2.2 Rpc客戶端
package main import ( "fmt" "log" "net/rpc" ) type Request struct { M, N int } func main() { // 與遠端RPC服務建立連線conn, err := rpc.DialHTTP("tcp" , "127.0.0.1:8081") if err != nil { log.Panicf("DialHTTP error, %s\n", err) return } // 呼叫遠端方法res := 0 req := Request{ M: 10, N: 20, } if err = conn.Call("serv.Multiply", req, &res); err != nil { log.Panicf("Call func error, %s\n", err) return } fmt.Printf( "%d x %d = %d", req.M, req.N, res) }
4. 總結
主要介紹了什麼是RPC,RPC的優缺點;主流RPC框架介紹,Golang中如何借助官方net/rpc
庫實現RPC服務於呼叫。下一篇我們一起來探討一下在Golang中如何借助Grpc實現RPC服務。