微服務系列(二)GRPC的介紹與安裝
微服務系列(二)GRPC的介紹與安裝
1.GPRC簡介
GRPC是Google公司基於Protobuf開發的跨語言的開源RPC框架。GRPC基於HTTP/2協議設計,可以基於一個HTTP/2鏈接提供多個服務,對於移動設備更加友好。目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go. 其中 C 版本支援 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支援.
在 gRPC里客戶端應用可以像調用本地對象一樣直接調用另一台不同的機器上服務端應用的方法,使得您能夠更容易地創建分散式應用和服務。與許多 RPC系統類似, gRPC也是基於以下理念:
-
定義一個服務,指定其能夠被遠程調用的方法(包含參數和返回類型)。
-
在服務端實現這個介面,並運行一個 gRPC伺服器來處理客戶端調用。
在客戶端擁有一個存根能夠像服務端一樣的方法。 gRPC客戶端和服務端可以在多種環境中運行和交互 -從 google內部的伺服器到你自己的筆記型電腦,並且可以用任何 gRPC支援的語言 來編寫。
所以,你可以很容易地用 Java創建一個 gRPC服務端,用 Go、 Python、Ruby來創建客戶端。此外, Google最新 API將有 gRPC版本的介面,使你很容易地將 Google的功能集成到你的應用里。
參考資料
gRPC 官方文檔中文版://doc.oschina.net/grpc?t=60133
gRPC官網://grpc.io
再詳細了解使用GRPC之前先來了解一下上面定義中的一些關鍵詞。
首先我們來看一下HTTP/2是什麼內容?
其實本質上就是http2.0版本,http目前為止主要有四個版本,分別為http1.0、http1.1、http2.0、https。
http1.0是最原始的版本,不支援持久連接,效率也比較低
http1.1針對http1.0版本做了優化,可以連接一次,多次使用,效率比http1.0高
http2.0實現了多路復用,對http1.1再次進行了優化。http2.0也被稱為下一代http協議,是在2013年8月進行首次測試,所以現在用的不是很廣。
https其實是在http協議上多加了一層SSL協議,具體如下圖:

所以本質上,http1.0、http1.1、http2.0都可以添加SSL協議。
2. grpc環境安裝
-
官方推薦安裝方法:
go get -u -v google.golang.org/grpc但是由於牆原因,不能直接訪問google官網,所以只能曲線救國了
-
通過github下載各種依賴庫,然後配置。
git clone //github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc git clone //github.com/golang/net.git $GOPATH/src/golang.org/x/net git clone //github.com/golang/text.git $GOPATH/src/golang.org/x/text git clone //github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto cd $GOPATH/src/ go install google.golang.org/grpc網路暢通可以用上述方法,但如果網速較慢,我們也可以選擇離線安裝方法。
-
用
x.zip和google.golang.org.zip兩個離線包來安裝。#將x.zip 解壓到 $GOPATH/src/golang.org/x 目錄下 $ unzip x.zip -d $GOPATH/src/golang.org/x #將google.golang.org.zip 解壓到 $GOPATH/src/google.golang.org 目錄下 $ unzip google.golang.org.zip -d $GOPATH/src/google.golang.org #然後進入到$GOPATH/src/google.golang.org/grpc下面執行go install $ go install點擊此處獲取兩個離線壓縮包
3.GRPC使用
如果從Protobuf的角度看,GRPC只不過是一個針對service介面生成程式碼的生成器。接著我們來學習一下GRPC的用法。這裡我們創建一個簡單的proto文件,定義一個HelloService介面:
文件名稱為person.proto
syntax = "proto3";
package pb; // 後期生成go的文件包名
option go_package = "../pb"; // go 1.14後需要指定導出的路徑
// 消息體 -- 一個package中,不允許定義同名的消息體
message Teacher {
int32 age = 1;
string name = 2;
}
// 定義服務
service SayName {
rpc SayHello(Teacher) returns (Teacher);
}
對proto文件進行編譯:
protoc --go_out=plugins=grpc:./ person.proto
編譯後生成person.pb.go文件
GRPC插件會為服務端和客戶端生成不同的介面:
//客戶端介面
type SayNameClient interface {
SayHello(ctx context.Context, in *Teacher, opts ...grpc.CallOption) (*Teacher, error)
}
//伺服器介面
type SayNameServer interface {
SayHello(context.Context, *Teacher) (*Teacher, error)
}
我們接著可以基於他們給的服務端介面重新實現SayHello服務:
// 定義一個結構體 不一定非得是Teacher
type Children struct {
}
// 介面去綁定類方法
func (c *Children) SayHello(ctx context.Context,t *pb.Teacher) (*pb.Teacher, error) {
t.Name += "is teaching"
return t,nil
}
GRPC的啟動流程和RPC的啟動流程類似,程式碼如下:
func main(){
// 1. 初始一個grpc對象
grpcServer := grpc.NewServer()
// 2.註冊服務
pb.RegisterSayNameServer(grpcServer,new(Children))
// 3.設置監聽並建立連接,指定IP port
listener ,err := net.Listen("tcp","127.0.0.1:8080")
if err!=nil{
fmt.Printf("監聽失敗:%v",err)
return
}
defer listener.Close()
fmt.Println("正在監聽127.0.0.1:8080 ...")
// 4.啟動服務 ... Serve()
grpcServer.Serve(listener)
}
然後我們就可以通過客戶端來連接GRPC服務了:
func main(){
// 1.連接grpc服務
grpcConn,err := grpc.Dial("127.0.0.1:8080",grpc.WithInsecure()) // 第二個參數以一個安全的形式進行編譯
if err!=nil{
fmt.Printf("連接撥號失敗:%v",err)
return
}
defer grpcConn.Close()
// 2.初始化grpc客戶端
grpcClient := pb.NewSayNameClient(grpcConn) // 傳入Dail函數的返回值
// 創建並初始化Teacher對象
var teacher pb.Teacher
teacher.Name = "小寶"
teacher.Age = 24
// 3.調用遠程服務
t,err := grpcClient.SayHello(context.TODO(),&teacher) /*context.TODO()表示空對象,可以簡單理解我們不清楚要使用哪個上下文、或者還沒有可用的上下文時的佔位符*/
if err!=nil{
fmt.Printf("調用遠程服務失敗:%v",err)
return
}
fmt.Println(t)
}
