5 分で gRPC を学びましょう。学びましたか?

5 分で gRPC を学びましょう。学びましたか?

導入

長い間 Java を使ってきた開発者のほとんどは、gRPC に触れることはほとんどないと思います。結局のところ、Java 界隈で使用されているサービス フレームワークのほとんどは Dubbo/SpringClound です。

私も最近、ビジネスをゼロから再構築する機会があり、gRPC と出会いました。 gRPC を選択した理由はいくつかあります。

  • gRPC がほぼ標準的な通信プロトコルであるクラウドネイティブのアイデアに基づいてプロジェクトを開発および展開します。
  • 開発言語として Go が選択されましたが、Go コミュニティでは gRPC の方が明らかに優れた選択肢です。
  • 社内業務の一部はPythonで開発されており、gRPCは多言語対応が非常に優れています。

オンラインで 1 年以上安定して運用されてきた結果、gRPC は依然として非常に安定しており、効率的であることがわかります。 rpc フレームワークの中核となるポイントは次のとおりです。

  • シリアル化
  • 通信プロトコル
  • IDL (インターフェース記述言語)

これらは以下に対応します:

  • Protocol Buffer シリアル化プロトコルに基づいており、高いパフォーマンスを備えています。
  • HTTP/2標準プロトコルをベースに開発されており、ストリームや多重化などの機能が組み込まれています。同時に、標準プロトコルであるため、サードパーティツール(負荷分散、監視など)との互換性が向上します
  • .proto インターフェース ファイルを作成することで、共通言語コードを生成できます。

HTTP/2

gRPC を学習する前に、まず gRPC がどのようなプロトコルを介して通信するかを知っておく必要があります。私たちの日常的な開発やアプリケーションでは、基本的に HTTP/1.1 プロトコルに最も多く触れます。

HTTP/1.1 はテキスト プロトコルであるため、人間にとっては非常に使いやすいですが、マシン上でのパフォーマンスは比較的低くなります。

テキストを繰り返し解析する必要があるため、効率は当然低くなります。よりマシンフレンドリーにするにはバイナリを使用する必要がありますが、これは HTTP/2 によって自然に実現されます。

他にも利点があります:

  • 多重化: メッセージは互いに影響を与えることなく並行して送受信できます
  • HPACK はヘッダースペースを節約し、HTTP1.1 が同じヘッダーを繰り返し送信するのを防ぎます。

プロトコル

gRPC は、gRPC より前にリリースされたプロトコル シリアル化を使用します。したがって、gRPC だけでなく、シリアル化された IO 操作を必要とするあらゆるシナリオで使用できます。

より省スペースで高性能になります。 https://github.com/crossoverJie/cim の開発時にデータのやり取りに使用されました。

パッケージ順序.v1 ;

サービス OrderService {

rpc Create ( OrderApiCreate )( Order )を返します{ }

rpc Close ( CloseApiCreate )( Order )を返します{ }

//サーバープッシュ
rpc ServerStream ( OrderApiCreate )( stream Order )を返します{ }

//クライアントプッシュ
rpc ClientStream (ストリーム OrderApiCreate )( Order )を返します{ }

//双方向プッシュ
rpc BdStream (ストリーム OrderApiCreate )(ストリームOrder )を返します{ }
}

メッセージ OrderApiCreate {
int64 オーダーID = 1 ;
繰り返し int64 user_id = 2 ;
文字列コメント= 3 ;
繰り返し int32 reason_id = 4 ;
}

使い方も非常に簡単です。独自の .proto ファイルを定義するだけで、コマンドライン ツールを使用して対応する言語の SDK を生成できます。

詳細については、公式ドキュメントを参照してください: https://grpc.io/docs/languages/go/generated-code/

電話

 プロトコル--go_out=。 --go_opt=パス=ソース相対\
--go-grpc_out= を指定します。 --go-grpc_opt=パス=ソース相対\
テスト.proto

コードが生成されると、サーバーの作成は非常に簡単になります。生成されたインターフェースを実装するだけで済みます。

 func ( o * Order ) Create ( ctx context .Context , in * v1 .OrderApiCreate ) ( * v1 .Order , error ) {
//メタデータを取得
md ok : =メタデータ.FromIncomingContext ( ctx )
もしわかりました{
nil ステータス.Errorf (コード.DataLoss "メタデータの取得に失敗しました" )を返します
}
fmt .Println ( md )
fmt .Println ( .OrderId )
戻り値& v1 .Order {
OrderId : .OrderId
理由:なし
} ゼロ
}

クライアントも非常にシンプルで、サーバー コードに依存して接続を作成し、ローカル メソッドを呼び出すだけです。

これは、1 つのリクエストが 1 つのレスポンスに対応する、http のリクエスト/レスポンス モデルに似た、典型的な単項呼び出しです。

サーバーストリーム

gRPC は、通常の単項呼び出しに加えて、特定のシナリオで非常に便利なサーバー プッシュもサポートしています。

 func ( o * Order ) ServerStream ( in * v1 .OrderApiCreate , rs v1 .OrderService_ServerStreamServer )エラー{
i : = 0の場合;< 5 ;私は++ {
rs .Send ( & v1 .Order {
OrderId : .OrderId
理由:なし
}
}
ゼロを返す
}

サーバーのプッシュ機能は上記に示されています。プッシュ関数を呼び出してクライアントにプッシュすることができます。

 のために{
メッセージエラー: = rpc.RecvMsg ( )
err == io.EOFの場合{
marshalIndent , _ : = json .MarshalIndent ( msgs , "" , "\t" )
fmt .Println (メッセージ)
戻る
}
}

クライアントは、ループ内で現在受信されているデータ パケットが終了したかどうかを判定することによって、サーバー メッセージを取得します。

このプロセスをより直感的に示すために、以前に開発された gRPC クライアントが、ストリーム呼び出しを直感的にデバッグできるように最適化されました。

上の図はサーバープッシュの例です。

クライアントストリーム

サーバー プッシュのサポートに加えて、クライアントもそれをサポートします。

クライアントは同じ接続でサーバーにデータを送信し続け、サーバーはメッセージを並行して処理できます。

 //サーバーコード
func ( o * Order ) ClientStream ( rs v1 .OrderService_ClientStreamServer )エラー{
var 値[ ] int64
のために{
受信,エラー: = rs .受信( )
err == io.EOFの場合{
rs .SendAndClose ( & v1 .Order {
注文ID : 100
理由:なし
}
log .Println ()
ゼロを返す
}
value = append ( recv.OrderId )
log .Printf ( "ClientStream 受信メッセージ %v" recv .OrderId )
}
log .Println ( "ClientStream 終了" )
ゼロを返す
}

//クライアントコード
i : = 0の場合;< 5 ;私は++ {
メッセージ _ : = GetMsg (データ)
rpc .SendMsg (メッセージ[ 0 ] )
}
受信エラー: = rpc.CloseAndReceive ( )

コードはサーバー プッシュに似ていますが、役割が入れ替わります。

双方向ストリーム

同様に、クライアントとサーバーの両方が同時にメッセージを送信する場合もサポートされます。

 //サーバー
func ( o * Order ) BdStream ( rs v1 .OrderService_BdStreamServer )エラー{
var 値[ ] int64
のために{
受信,エラー: = rs .受信( )
err == io.EOFの場合{
log .Println ()
ゼロを返す
}
err != nil の場合{
パニックエラー
}
value = append ( recv.OrderId )
log .Printf ( "BdStream 受信メッセージ %v" recv .OrderId )
rs .SendMsg ( & v1 .Order {
注文ID :受信.注文ID
理由:なし
}
}
ゼロを返す
}
//クライアント
i : = 0の場合;< 5 ;私は++ {
メッセージ _ : = GetMsg (データ)
//メッセージを送信する
rpc .SendMsg (メッセージ[ 0 ] )
//メッセージを受信する
受信 _ : = rpc.RecvMsg ( )
marshalIndent , _ : = json .MarshalIndent (受信, "" , "\t" )
fmt .Println (文字列( marshalIndent ) )
}
rpc.CloseSend ( ) 関数

実際のところ、それは単に 2 つの訴えを 1 つに組み合わせただけです。

例を挙げるとわかりやすいです。

メタデータ

gRPC は、HTTP のヘッダーと同様に、メタデータの送信もサポートしています。

 //クライアントが書き込み
metaStr : = ` { "lang" : "zh" } `
var m map [文字列]文字列
err : = json .Unmarshal ( [ ] byte ( metaStr ) , & m )
md : =メタデータ。新着( m )
//呼び出すときにctxを渡すだけです
ctx : =メタデータ.NewOutgoingContext (コンテキスト.Background ( ) , md )

//サーバーは受信
md ok : =メタデータ.FromIncomingContext ( ctx )
もしわかりました{
nil ステータス.Errorf (コード.DataLoss "メタデータの取得に失敗しました" )を返します
}
fmt .Println ( md )

gRPC ゲートウェイ

gRPC は強力で使いやすいですが、ブラウザやアプリのサポートは REST ほど広まっていません (ブラウザもサポートしていますが、アプリケーションは非常に少ないです)。

この目的のために、コミュニティは https://github.com/grpc-ecosystem/grpc-gateway プロジェクトを作成しました。このプロジェクトでは、gRPC サービスを RESTFUL API として公開できます。

テスターがインターフェース テストに postman を使用することに慣れるために、より便利なテストのために gRPC サービスもプロキシします。

リフレクションコール

RPC フレームワークとして、サポート ツールの開発を容易にするために、一般化された呼び出しもサポートする必要があります。 gRPC はリフレクションを通じてサポートされており、サービス名と pb ファイルを取得することでリフレクション呼び出しが行われます。

https://github.com/jhump/protoreflect このライブラリは、一般的なリフレクション操作をカプセル化します。

上の図に示されている視覚化ストリーム呼び出しも、このライブラリを通じて実装されています。

負荷分散

gRPC は HTTP/2 に基づいて実装されているため、クライアントとサーバーは長時間の接続を維持します。負荷分散は HTTP ほど単純ではありません。

接続ではなくリクエストの負荷分散を必要とする gRPC を使用して、HTTP と同じ効果を実現したいと考えています。

通常、2 つのアプローチがあります。

  • クライアント負荷分散
  • サーバー側の負荷分散

クライアント負荷分散は、RPC 呼び出しで広く使用されています。たとえば、Dubbo はクライアント負荷分散を使用します。

gRPC は関連するインターフェースも提供します。詳細については公式デモを参照してください。

https://github.com/grpc/grpc-go/blob/87eb5b7502/examples/features/load_balancing/README.md

クライアント側の負荷分散は開発者にとって比較的柔軟性が高く (独自の戦略をカスタマイズできます)、開発者自身でロジックを維持する必要もあります。複数の言語がある場合は、複数のコピーを維持する必要があります。

したがって、クラウド ネイティブの一般的なテーマでは、サーバー側の負荷分散を使用することがより推奨されます。

オプションは次のとおりです:

  • イスティオ
  • 特使
  • アピックス

私たちもこの分野を研究しており、おそらく envoy/istio を使用する予定です。

要約する

gRPC にはまだ多くのコンテンツがあります。この記事は、gRPC を知らない人に基本的な理解を与えることを目的とした入門文書です。これはまさにクラウドネイティブ時代に必要なスキルです。

この記事の gRPC クライアントに興味のある方は、ここのソース コードを参照してください: https://github.com/crossoverJie/ptg。

<<:  Tektonシリーズに関する理論的な記事

>>:  Kubernetes で絶対にしてはいけない 10 の間違い

推薦する

サーバー仮想化の将来はどうなるのでしょうか?

サーバー仮想化は、過剰なサーバー リソースの消費を抑え、コンピューターのパワーをより有効に活用し、エ...

26日午前、DNS障害によりCCTVやNetEaseなど有名サイトへのアクセスが不可能となった。

A5ウェブマスターネットワーク(admin5.com)は3月26日、多くのネットユーザーやウェブマス...

小規模ゲームウェブサイトの SEO 戦争: 内部最適化分析

正直に言うと、4399ミニゲームプロダクトマネージャーのYin Jinqian氏の「大規模なキーワー...

コンテナとKubernetesを活用した3つの変革成功事例

さまざまな業界の企業が、デジタル変革の一環として、あるいは増大する需要に対応するために構築される高価...

SEOサービス業界には3つの柱があり、起業界の混乱の中で3つの王国が出現した

三国時代には三つの勢力が対立していたと言われており、『三国志演義』は歴史上の最高傑作です。しかし今、...

インスタント メッセージング ソフトウェアの「10 年間の進化」

【ゼロからのスタート】 2003 年には、QQ や NetEase Bubble などのインスタント...

ウェブマスターネットワークからの毎日のレポート:テンセントはタオバオ+JD.com WeChatを実施し、張小龍時代に別れを告げる

1. ヤフーが今夏、広告テクノロジー企業AppNexusの株式を取得する計画があると噂されている。海...

5 つ星評価システムは信頼できないのでしょうか? 映画サイトにもっと良い選択肢はありますか?

多くの人がオンラインで映画リソースを探すとき、まず映画の評価を見て、それから比較的評価の高い映画を選...

新しいサイトに権限がない場合はどうなるでしょうか?新しいサイトBaiduを重くする方法をお教えします

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスウェブサイトのBaidu...

鉱業博覧会の「クラウド」ツアー 天一クラウドと鉱業博覧会が鉱業博覧会と協力し、スマート鉱業博覧会クラウドを創出

5G、クラウドコンピューティング、VR、AR技術の急速な発展により、クラウド展示会は主要展示会の「寵...

Amazon Web Services: ゲーム業界の革新と再編を実現

「マリオ」や「テトリス」の初期の時代から、今日の人気の「原神」まで、世界のゲーム業界は過去 70 年...

Docker をすぐに使い始めるのに役立つ 6 つのツール

Docker テクノロジがより多くの人々に認知されるにつれて、その適用範囲はますます広がっています。...

WeChat StoresがTaobaoに挑戦:電子商取引へのアクセスには基準はないが、2万元のデポジットが必要

概要:WeChatパブリックプラットフォームは昨日、「WeChatストア」を正式に開始しました。We...

profvds: スロバキア VPS、メール用にポート 25 を開放、トラフィック制限なしの 1Gbps 帯域幅、月額 10 ユーロ、3G RAM/1 コア/20g ハード ドライブ

profvds は現在、主にスロバキアの VPS サービスを提供しています。デフォルトでは、ポート ...

Baidu Statisticsは役に立つのか?Baidu Statisticsのメリットとデメリットの紹介

これはBaidu統計に関する記事です。ウェブサイト運用関連の分野で働く人であれば、誰でもウェブサイト...