Golang gRPC學習(01): gRPC介紹


gRPC 是什么

gRPC是goole開源的一個RPC框架和庫,支持多語言之間的通信。底層通信采用的是 HTTP2 協議。gRPC在設計上使用了 ProtoBuf 這種接口描述語言。這種IDL語言可以定義各種服務,google還提供了一種工具 protoc 來編譯這種IDL語言,生成各種各樣的語言來操作服務。

gPRC特點

  • 定義服務簡單,可以很快的搭建出一個RPC調度的服務
  • gRPC是與語言無關,平台無關的。你定義好了一個protobuf協議,就可以用protoc生成不同語言的協議框架
  • 使用HTTP2協議,支持雙向流。客戶端和服務端可以雙向通信

image.png

gRPC為了解決什么問題

gRPC其實就是一種RPC,解決服務的遠程過程調用問題。
它使得我們遠程調用就像調用本地函數一樣,程序員無需關心交互的細節。

RPC與RESTful區別是什么

  • 在客戶端和服務端通信還有一種基於http協議的 RESTful 架構模式,RESTful一般是對於資源的操作,它是名詞(資源地址),然后添加一些動作對這些資源進行操作。
    而RPC是基於函數,它是動詞。

  • RPC一般基於TCP協議,當然gRPC是基於HTTP2,但它也是比HTTP協議更加有效率和更多特性。
    RESTful一般都是基於HTTP協議

  • 傳輸方面:自定義的TCP協議或者使用HTTP2協議,報文體積更小,所以傳輸效率更高
                    RESTful一般基於http協議,報文體積大

  • gRPC用的是protobuf的IDL語言,會編碼為二進制協議的數據,而RESTful一般是用json的數據格式,所以json格式的編解碼更耗時

為什么還是有很多公司用RESTful

以函數為基礎的模式(RPC),如果服務端添加了一個函數,那么客戶端也必須添加一個函數。
而以資源為操作基礎的RESTful,URI對應的服務變化了,客戶端一般是不需要關心和更新的,它對客戶端是透明的。
所以RPC的操作變更,有時比RESTful的復雜,因為RCP需要2邊都要添加代碼,也就增加了工作量。

並且json格式是可閱讀的格式,gRPC編碼后是二進制格式,對人不友好,不利於閱讀.
調試排錯RPC也比RESTful難,畢竟HTTP大家都很熟悉,而RPC協議一般是自定義協議,需要程序員自己去研究。

那怎么選擇呢?RPC OR RESTful

一般公司內部服務並發大,效率要求比較高的,可以用RPC。所以一般大公司內部用RPC比較多。不過大公司對外提供的api很多都是基於http的RESTful,為什么?因為這個簡單、易懂,大家都熟悉,使用就方便。

而業務量比較小,並發小,可以直接用RESTful,json,不管是公司內部服務間通信,還是對外提供api服務。

所以選擇:都是根據自己公司業務需求來判斷,適合使用哪種,就選擇哪種,不要盲目跟風,造成公司不必要的資源浪費。

golang中使用RESTful,用json傳輸數據,一般使用 https://github.com/gorilla/mux , https://github.com/gin-gonic/gin, https://github.com/labstack/echo,https://github.com/emicklei/go-restful
golang中的RPC現在一般使用g家的gRPC, https://grpc.io/, 畢竟大家都相信g家的技術實力 - -!

Protocol Buffers

這是google開源的並且非常成熟的用於數據結構序列化的框架。Protocol Buffers在github上的地址.
使用protocol來序列化數據,需要編寫一個proto文件,在proto文件中定義你的服務,rpc操作,返回和請求數據格式。
protocol buffers的數據是一個結構化的消息,每個消息都是一小的邏輯信息的記錄,消息中包含了一系列的鍵值對,稱之為屬性,一個簡單的例子:

message Person {
   string name = 1;
   int32 age = 2;
   bool isPay = 3;       
}

定義了你傳輸的數據結構,就可以用protoc來生成對應語言的代碼。這些代碼提供了方法,可以操作每個屬性,可以將數據序列化為元數據傳輸給對方,也可以將對方發送過來的元數據進行解析。
例子:

// The greeter service definition.
service Greeter {
   //Sends a greeting
   rpc SayHello (HelloRequest) returns (HelloReply) {}
}
 
// The request message containing the user's name.
message HelloRequest {
   string name = 1;
}
 
//The response message containing the greetings
message HelloReply {
   string message = 1;
}

gRPC可以使用帶插件的 protoc 命令,將你編寫的proto文件生成代碼。使用gRPC的插件的時候,你可以生成gRPC的客戶端和服務端代碼,和一般的protocol buffers代碼一樣,
可以構建,序列化,反序列化消息。

Protocol Buffer 官方文檔: https://developers.google.com/protocol-buffers/docs/overview
從這里也可以獲取 protoc 插件,從而生成你擅長語言的代碼。

gRPC的四種定義方式

gRPC允許用戶定義四種形式的rpc方法(原文參照:https://grpc.io/docs/guides/concepts.html):

A.客戶端發送請求到服務端,然后服務端給出一個響應,就像一個普通的方法定義一樣,如下所示:

rpc SayHello(HelloRequest) returns (HelloResponse) {};

B.服務端的流式rpc:客戶端發送一個請求到服務端,然后得到一個流用於讀取服務端的的消息,客戶端從返回的流中讀取所有的信息,如下所示:

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse) {};

C.客戶端流式rpc: 客戶端使用流將信息發送個服務端,只要客戶端發送完所有的信息給服務器,就開始等待服務端的響應,如下所示:

rpc LotsOfGreeting(stream HelloRequest) returns (HttpResponse) ;

D.雙向流式rpc:服務端與客戶端都是用讀寫流發送數據給對方。這兩個流式相互獨立的,所以他們的讀寫可以是任意順序的,例如:服務端在接受到客戶的所有的信息之前就已經開始響應,
也可以先讀取數據然后再寫數據,或者其他任何組合,如下所示:

rpc SayHello(stream HelloRequest) returns (HelloResponse) ;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM