Go gRPC 系列一:相關介紹

你們好,我是煎魚,做爲開篇章,今天將會介紹 gRPC 相關的一些知識。簡單來說 gRPC 是一個 基於 HTTP/2 協議設計的 RPC 框架,它採用了 Protobuf 做爲 IDLgit

你是否有過疑惑,它們都是些什麼?本文將會介紹一些經常使用的知識和概念,更詳細的會給出手冊地址去深刻github

1、RPC

什麼是 RPC

RPC 代指遠程過程調用(Remote Procedure Call),它的調用包含了傳輸協議和編碼(對象序列號)協議等等。容許運行於一臺計算機的程序調用另外一臺計算機的子程序,而開發人員無需額外地爲這個交互做用編程apache

實際場景:

有兩臺服務器,分別是A、B。在 A 上的應用 C 想要調用 B 服務器上的應用 D,它們能夠直接本地調用嗎?
答案是不能的,但走 RPC 的話,十分方便。所以常有人稱使用 RPC,就跟本地調用一個函數同樣簡單編程

RPC 框架

我認爲,一個完整的 RPC 框架,應包含負載均衡、服務註冊和發現、服務治理等功能,並具備可拓展性便於流量監控系統等接入
那麼它纔算完整的,固然了。有些較單一的 RPC 框架,經過組合多組件也能達到這個標準json

你認爲呢?安全

常見 RPC 框架

比較一下

\ 跨語言 多 IDL 服務治理 註冊中心 服務管理
gRPC × × × ×
Thrift × × × ×
Rpcx ×
Dubbo ×

爲何要 RPC

簡單、通用、安全、效率bash

RPC 能夠基於 HTTP 嗎

RPC 是代指遠程過程調用,是能夠基於 HTTP 協議的服務器

確定會有人說效率優點,我能夠告訴你,那是基於 HTTP/1.1 來說的,HTTP/2 優化了許多問題(固然也存在新的問題),因此你看到了本文的主題 gRPC網絡

2、Protobuf

介紹

Protocol Buffers 是一種與語言、平臺無關,可擴展的序列化結構化數據的方法,經常使用於通訊協議,數據存儲等等。相較於 JSON、XML,它更小、更快、更簡單,所以也更受開發人員的青眯app

語法

syntax = "proto3";

service SearchService {
    rpc Search (SearchRequest) returns (SearchResponse);
}

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message SearchResponse {
    ...
}
複製代碼

一、第一行(非空的非註釋行)聲明使用 proto3 語法。若是不聲明,將默認使用 proto2 語法。同時我建議用 v2 仍是 v3,都應當聲明其使用的版本

二、定義 SearchService RPC 服務,其包含 RPC 方法 Search,入參爲 SearchRequest 消息,出參爲 SearchResponse 消息

三、定義 SearchRequestSearchResponse 消息,前者定義了三個字段,每個字段包含三個屬性:類型、字段名稱、字段編號

四、Protobuf 編譯器會根據選擇的語言不一樣,生成相應語言的 Service Interface Code 和 Stubs

最後,這裏只是簡單的語法介紹,詳細的請右拐 Language Guide (proto3)

數據類型

.proto Type C++ Type Java Type Go Type PHP Type
double double double float64 float
float float float float32 float
int32 int32 int int32 integer
int64 int64 long int64 integer/string
uint32 uint32 int uint32 integer
uint64 uint64 long uint64 integer/string
sint32 int32 int int32 integer
sint64 int64 long int64 integer/string
fixed32 uint32 int uint32 integer
fixed64 uint64 long uint64 integer/string
sfixed32 int32 int int32 integer
sfixed64 int64 long int64 integer/string
bool bool boolean bool boolean
string string String string string
bytes string ByteString []byte string

v2 和 v3 主要區別

  • 刪除原始值字段的字段存在邏輯
  • 刪除 required 字段
  • 刪除 optional 字段,默認就是
  • 刪除 default 字段
  • 刪除擴展特性,新增 Any 類型來替代它
  • 刪除 unknown 字段的支持
  • 新增 JSON Mapping
  • 新增 Map 類型的支持
  • 修復 enum 的 unknown 類型
  • repeated 默認使用 packed 編碼
  • 引入了新的語言實現(C#,JavaScript,Ruby,Objective-C)

以上是平常涉及的常見功能,若是還想詳細瞭解可閱讀 Protobuf Version 3.0.0

相較 Protobuf,爲何不使用XML?

  • 更簡單
  • 數據描述文件只需原來的1/10至1/3
  • 解析速度是原來的20倍至100倍
  • 減小了二義性
  • 生成了更易使用的數據訪問類

3、gRPC

介紹

gRPC 是一個高性能、開源和通用的 RPC 框架,面向移動和 HTTP/2 設計

多語言

  • C++
  • C#
  • Dart
  • Go
  • Java
  • Node.js
  • Objective-C
  • PHP
  • Python
  • Ruby

特色

一、HTTP/2

二、Protobuf

三、客戶端、服務端基於同一份 IDL

四、移動網絡的良好支持

五、支持多語言

概覽

image

講解

一、客戶端(gRPC Sub)調用 A 方法,發起 RPC 調用

二、對請求信息使用 Protobuf 進行對象序列化壓縮(IDL)

三、服務端(gRPC Server)接收到請求後,解碼請求體,進行業務邏輯處理並返回

四、對響應結果使用 Protobuf 進行對象序列化壓縮(IDL)

五、客戶端接受到服務端響應,解碼請求體。回調被調用的 A 方法,喚醒正在等待響應(阻塞)的客戶端調用並返回響應結果

示例

在這一小節,將簡單的給你們展現 gRPC 的客戶端和服務端的示例代碼,但願你們先有一個基礎的印象,將會在下一章節詳細介紹 🤔

構建和啓動服務端

lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
        log.Fatalf("failed to listen: %v", err)
}

grpcServer := grpc.NewServer()
...
pb.RegisterSearchServer(grpcServer, &SearchServer{})
grpcServer.Serve(lis)
複製代碼

一、監聽指定 TCP 端口,用於接受客戶端請求

二、建立 gRPC Server 的實例對象

三、gRPC Server 內部服務和路由的註冊

四、Serve() 調用服務器以執行阻塞等待,直到進程被終止或被 Stop() 調用

建立客戶端

var opts []grpc.DialOption
...
conn, err := grpc.Dial(*serverAddr, opts...)
if err != nil {
    log.Fatalf("fail to dial: %v", err)
}

defer conn.Close()
client := pb.NewSearchClient(conn)
...
複製代碼

一、建立 gRPC Channel 與 gRPC Server 進行通訊(需服務器地址和端口做爲參數)

二、設置 DialOptions 憑證(例如,TLS,GCE憑據,JWT憑證)

三、建立 Search Client Stub

四、調用對應的服務方法

思考題

一、什麼場景下不適合使用 Protobuf,而適合使用 JSON、XML?

二、Protobuf 一節中提到的 packed 編碼,是什麼?

總結

在開篇內容中,我利用了儘可能簡短的描述給你介紹了接下來所必須、必要的知識點 但願你可以有所收穫,建議能到我給的參考資料處進行深刻學習,是最好的了

若是有任何疑問或錯誤,歡迎在 issues 進行提問或給予修正意見,若是喜歡或對你有所幫助,歡迎 Star,對做者是一種鼓勵和推動。

個人公衆號

image

參考資料

相關文章
相關標籤/搜索