GRPC從使用到深入 服務的定義和使用

2021-10-05 00:14:56 字數 3237 閱讀 6287

忽略底層細節,從使用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...