忽略底層細節,從使用rpc的角度,最主要的就是要定義乙個方法簽名。這個方法,由服務端去實現,由客戶端去呼叫。
因此我們關心一下幾方面:
①方法的引數:決定了客戶端要請求的資料;
②方法的返回值:決定了服務端要返回的資料;
③方法的名稱:決定了rpc要實現什麼功能;
從這個角度去看grpc的文件,發現他的方法定義不太好理解。
我們先看一下官網給的案例:
syntax = "proto3";
service routeguide
// a server-to-client streaming rpc.
rpc listfeatures(rectangle) returns (stream feature) {}
// a client-to-server streaming rpc.
rpc recordroute(stream point) returns (routesummary) {}
// a bidirectional streaming rpc.
rpc routechat(stream routenote) returns (stream routenote) {}
}
以上定義中
關鍵字rpc代表這是乙個服務的定義
另外乙個關鍵字 stream則是grpc的重要特性。我們從客戶端和服務端通訊的角度去理解它
最簡單的情況下:
這種情況很簡單,但是如果客戶端或者服務端之間的互動很頻繁時,每次方法呼叫都要建立連線,所以開銷比較大,grpc考慮了這一點,所以需要再定義客戶端和服務端是否為stream。這四種定義方式帶來的影響,我們通過grpc生成的**來分析。
public static abstract class routeguideimplbase
public void listfeatures(rectangle request,streamobserverresponseobserver){}
public streamobserverrecordroute(streamobserverresponseobserver){}
public treamobserverroutechat(streamobserverresponseobserver){}
}
這是需要我們繼承並實現的乙個抽象類。從這四個方法簽名去看,發現雖然服務定義有四種型別,但是生成的**只有兩種簽名。
不管是否定義了server-stream,grpc框架都為我們提供了乙個responseobserver, 這是乙個stream,服務端用它來返回相應資料。
至於client-stream,才是對方法簽名產生影響的唯一因素:
未定義為client-stream: 這就是開頭說的最簡單的行式,客戶端將請求資料一次性地傳送給服務端,服務端則直接處理完資料,然後通過responseobserver返回處理結果即可。
定義了client-stream: 這種情況下,服務端無法知道請求資料何時到達,也不知道請求資料何時結束。因此grpc框架要求我們自己實現乙個處理請求流資料的observer物件,即方法返回的streamobserver型別物件。 返回的整個observer物件會交給grpc框架去呼叫。
生成的客戶端**相對來說複雜一些,因為grpc為客戶端生成了三種存根:
public static routeguidestub newstub(channel channel)
public static routeguideblockingstub newblockingstub(channel channel)
public static routeguidefuturestub newfuturestub(channel channel)
這三種存根從名字也大概能猜出他們的功能
1.stub:提供完全非同步的方法
public static final class routeguidestub
public void listfeatures(rectangle request,streamobserverresponseobserver){}
public streamobserverrecordroute(streamobserverresponseobserver){}
public streamobserverroutechat(streamobserverresponseobserver){}
}
客戶端要使用stub,必須要先實現自己的responseobserver,用來處理服務端返回的訊息。
前面也說了,服務端的實現裡面,響應資料都是以stream的行式返回的,因此這部分很好理解。
區別仍然是client-stream部分。
1.未定義client-stream,則stub直接將客戶端準備好的資料放到前兩個方法的引數中,然後呼叫方法
2.定義了client-stream,這說明client無法一次性準備好請求資料,因此stub的後兩個方法呼叫後,grpc框架會返回乙個stream observer,這個物件供客戶端隨時呼叫,傳送stream行式的資料。
2.blockstub :提供完全同步的方法
public static final class routeguideblockingstub
public iteratorlistfeatures(rectangle request)
}
可以看到,blockstub只實現了未定義client-stream的服務,這也很好理解,既然是同步方法,那就要求一次呼叫就結束。
唯一需要說明的是,同步方法也實現了server-stream,其實blockstub是等服務端把資料都返回後,再一次性處理的,如果服務端一直沒有完成響應資料的返回,那麼listfeatures()方法會一直阻塞等待。
3.futruestub
public static final class routeguidefuturestub
}
可以看到,futurestub只實現了乙個方法,它其實就是解決了blockstub在處理server-stream的方法時阻塞的問題 Go微服務 grpc的簡單使用
我的是windows,將壓縮包bin目錄下的exe放到環境path目錄中即可。然後獲取外掛程式支援庫 grpc執行時介面編譯碼支援庫 從 proto檔案 grpc介面描述檔案 生成 go檔案 的編譯器外掛程式 go get u github.com golang protobuf protoc ge...
微服務優化之使用gRPC做微服務的內部通訊
grpc是乙個高效能的 開源的 普遍通用的rpc框架。簡單地說,它能夠幫助我們建立透明的服務端和客戶端通訊系統。google開發了grpc並且將其開源。通過它,乙個客戶端消費者服務可以像呼叫本地方法一樣,呼叫另一台主機上面的服務端方法。grpc本質上仍然遵循常規的remote procedure c...
微服務優化之使用gRPC做微服務的內部通訊
grpc是乙個高效能的 開源的 普遍通用的rpc框架。簡單地說,它能夠幫助我們建立透明的服務端和客戶端通訊系統。google開發了grpc並且將其開源。通過它,乙個客戶端消費者服務可以像呼叫本地方法一樣,呼叫另一台主機上面的服務端方法。grpc本質上仍然遵循常規的remote procedure c...