RPC是什么?
所謂RPC(remote procedure call 遠程過程調用)框架實際是提供了一套機制,使得應用程序之間可以進行通信,而且也遵從server/client模型。使用的時候客戶端調用server端提供的接口就像是調用本地的函數一樣。
gRPC是什么?
與許多RPC系統一樣,gRPC基于定義服務的思想,指定可以使用其參數和返回類型遠程調用的方法。默認情況下,gRPC使用協議緩沖區作為接口定義語言(IDL)來描述服務接口和有效負載消息的結構。
gRPC有什么好處以及在什么場景下需要用gRPC
既然是server/client模型,那么我們直接用restful api不是也可以滿足嗎,為什么還需要RPC呢?下面我們就來看看RPC到底有哪些優勢
gRPC vs. Restful API
gRPC和restful API都提供了一套通信機制,用于server/client模型通信,而且它們都使用http作為底層的傳輸協議(嚴格地說, gRPC使用的http2.0,而restful api則不一定)。不過gRPC還是有些特有的優勢,如下:
- gRPC可以通過protobuf來定義接口,從而可以有更加嚴格的接口約束條件。關于protobuf可以參見筆者之前的小文Google Protobuf簡明教程
- 另外,通過protobuf可以將數據序列化為二進制編碼,這會大幅減少需要傳輸的數據量,從而大幅提高性能。
- gRPC可以方便地支持流式通信(理論上通過http2.0就可以使用streaming模式, 但是通常web服務的restful api似乎很少這么用,通常的流式數據應用如視頻流,一般都會使用專門的協議如HLS,RTMP等,這些就不是我們通常web服務了,而是有專門的服務器應用。)
使用場景
- 需要對接口進行嚴格約束的情況,比如我們提供了一個公共的服務,很多人,甚至公司外部的人也可以訪問這個服務,這時對于接口我們希望有更加嚴格的約束,我們不希望客戶端給我們傳遞任意的數據,尤其是考慮到安全性的因素,我們通常需要對接口進行更加嚴格的約束。這時gRPC就可以通過protobuf來提供嚴格的接口約束。
- 對于性能有更高的要求時。有時我們的服務需要傳遞大量的數據,而又希望不影響我們的性能,這個時候也可以考慮gRPC服務,因為通過protobuf我們可以將數據壓縮編碼轉化為二進制格式,通常傳遞的數據量要小得多,而且通過http2我們可以實現異步的請求,從而大大提高了通信效率。
但是,通常我們不會去單獨使用gRPC,而是將gRPC作為一個部件進行使用,這是因為在生產環境,我們面對大并發的情況下,需要使用分布式系統來去處理,而gRPC并沒有提供分布式系統相關的一些必要組件。而且,真正的線上服務還需要提供包括負載均衡,限流熔斷,監控報警,服務注冊和發現等等必要的組件。不過,這就不屬于本篇文章討論的主題了,我們還是先繼續看下如何使用gRPC。
gRPC的使用通常包括如下幾個步驟
- 通過protobuf來定義接口和數據類型
- 編寫gRPC server端代碼
- 編寫gRPC client端代碼
protobuf的安裝
mac:brew install protobuf
windows:protoc 下載:官方地址,然后將 bin 路徑添加到 path 環境變量下去
linux:
安裝需要的依賴包:
1
2
3
|
[root@localhost ~] # yum -y install autoconf automake libtool curl make g++ unzip [root@localhost ~] # unzip protobuf-master.zip [root@localhost ~] # cd protobuf-master |
生成configure文件的腳本文件,如果不執行這步,以下操作將通不過
1
2
|
[root@localhost protobuf-master] # ./autogen.sh [root@localhost protobuf-master] # ./configure |
可以修改安裝目錄通過 ./configure --prefix=命令,統一安裝在/usr/local/protobuf下
1
2
3
4
5
|
[root@localhost protobuf-master] # ./configure --prefix=/usr/local/protobuf [root@localhost protobuf-master] # make [root@localhost protobuf-master] # make check [root@localhost protobuf-master] # make install [root@localhost protobuf-master] # ldconfig # refresh shared library cache. |
安裝成功
1
|
[root@localhost protobuf-master] # protoc -I=./ --cpp_out=./ test.proto |
安裝grpc包
1
2
3
|
go get -u google.golang.org /grpc protoc --go_out=plugins=grpc:. *.proto |
定義接口和數據類型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
syntax = "proto3"; package rpc_package; // define a service service HelloWorldService { // define the interface and data type rpc SayHello (HelloRequest) returns (HelloReply) {} } // define the data type of request message HelloRequest { string name = 1; } // define the data type of response message HelloReply { string message = 1; } |
使用protobuf生成工具生成對應語言的庫函數
1
|
protoc --go_out=plugins=grpc:. helloworld.proto |
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
// server.go import ( "log" "net" "golang.org/x/net/context" "google.golang.org/grpc" pb "helloworld/helloworld" ) const ( port = ":50051" ) type server struct {} func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name}, nil } func main() { lis, err := net.Listen("tcp", port) if err != nil { log.Fatal("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) s.Serve(lis) } |
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package main //client.go import ( "log" "os" "golang.org/x/net/context" "google.golang.org/grpc" pb "helloworld/helloworld" ) const ( address = "localhost:50051" defaultName = "world" ) func main() { conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatal("did not connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn) name := defaultName if len(os.Args) >1 { name = os.Args[1] } r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) if err != nil { log.Fatal("could not greet: %v", err) } log.Printf("Greeting: %s", r.Message) } |
以上就是golang 微服務之gRPC與Protobuf的使用的詳細內容,更多關于golang gRPC與Protobuf的資料請關注服務器之家其它相關文章!
原文鏈接:https://segmentfault.com/a/1190000021851189