grpc入門(一)
一.什么是grpc
grpc是谷歌開源的一款高性能的rpc框架 (https://grpc.io),可以使用protocol buffers作為IDL(Interface Definition Language)文件,也可以作為底層的信息傳輸的格式(這也是本博文所介紹的方式)。
以下內容屬於筆者對 what is grpc? 的翻譯,原文請見: https://grpc.io/docs/guides/index.html。
grpc的客戶端應用可以像訪問本地方法一樣調用其他機器上的服務端應用的方法,使得我們可以非常簡單的創建分布式應用與服務。和其他很多rpc框架一樣,gprc也是創建一個服務接口,然后指定調用遠程方法所需的參數和返回類型。在服務端,需要實現服務的接口,然后啟動一個服務器來處理客戶端的調用;在客戶端,需要樁代碼,提供與服務端相同的方法。
grpc的客戶端與服務端可以在不同的環境下相互調用,例如: 從谷歌內部的服務到我們的桌面應用,這些應用可以使用gprc所支持的不同的語言來實現。因此,你可以使用grpc輕松的創建一個java的服務端應用,使用go或者python或者ruby語言創建一個客戶端應用。另外一方面,谷歌最近的所公布的一些接口使用了grpc,如此一來,你可以將谷歌的一些功能集成到你的應用中。
grpc默認采用了protocol buffers, 這是google已經開源了的並且非常成熟的用於數據結構序列化的框架(也可以使用其他的數據格式例如json)。在這里快速的介紹他的用法,如果你對protocol buffers已經非常熟悉額了,你可以跳過這篇文章直接進入到下一個章節。
首先,當使用protocol buffers來序列化數據,需要編寫一個proto文件,文件中定義你想要序列化的結構數據,注意文件名必須以 .proto結尾。protocol buffers的數據是一個結構化的消息,每個消息都是一小的邏輯信息的記錄,消息中包含了一系列的鍵值對,稱之為屬性,下面有一個簡單的例子:
message Person { string name = 1; int32 age = 2; bool has_ponycopter = 3; }
接着,當你已經制定了你的數據結構,你就可以使用protocol buffers編譯命令protoc來生成你所擅長的語言對應的類。類中提供了簡單的方法來操作每個屬性(例如name()和set_name()), 另外這些方法內部可以將數據序列化為元數據傳輸給對方,也可以將對方發送過來的元數據進行解析。拿一個具體的例子來說,如果你使用的是c++,編譯如上的例子后會生成一個叫做Person的類,你可以使用這個類來構建,序列化,並且得到 Person對應的protocol buffers消息。
下面會給出一個更加詳細的例子,你可以在一個普通的proto文件中定義grpc的服務,rpc的方法的參數和返回類型需要聲明為一個protocol buffers的消息。
// 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 Buffers document 文檔中獲取更多關於protocol buffers的說明,也可以從中學到如何獲得和安裝你所擅長的編程語言的 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 BidiHello(stream HelloRequest) returns HelloResponse {}