帶入gRPC:gRPC及相關介紹

原文地址:帶入gRPC:gRPC及相關介紹html

項目地址:go-grpc-examplegit

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

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

1、RPC

什麼是 RPC

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

實際場景:

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

RPC 框架

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

你認爲呢?segmentfault

常見 RPC 框架

比較一下

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

爲何要 RPC

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

RPC 能夠基於 HTTP 嗎

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

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

2、Protobuf

介紹

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

語法

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 編碼,是什麼?

總結

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

系列目錄

參考資料

相關文章
相關標籤/搜索