GRPC ホリスティックラーニング

高性能、クロス言語、クロスプラットフォームの RPC フレームワークです

なぜ

アドバンテージ

  1. protobuf バイナリ メッセージ、優れたパフォーマンス/高効率 (優れたスペースと時間の効率)

  1. GRPC は protobuf を通じてインターフェイスを定義できるため、より厳格なインターフェイス制約を設けることができます。

欠点がある

  1. GRPC は接続プールを提供していないため、独自に実装する必要があります

  1. 「サービスディスカバリ」および「ロードバランシング」メカニズムは提供されていません

  1. Protobuf バイナリの可読性が低い

どうやって

  1. 依存関係を追加する

    1. https://github.com/grpc/grpc-java/blob/master/README.md

  1. pbファイルを定義する

  2.  

  3. プラグインを通じて Java ファイルを生成する

  1.  

ソースコード分析

全体的なアーキテクチャ

 

サービス登録 (レジストリ パック) は、メソッド呼び出しモジュールによるクエリ用にサービスの説明、インターフェイスの説明、およびその他の情報を登録する役割を果たします。

メソッド呼び出し (Call Pack) は実際のメソッド呼び出しロジックであり、最終的には実装したサービス インターフェイスに対応するメソッドを呼び出します。

ネットワーク ストリーム (ストリーム パック) は、メソッド呼び出しのネットワーク セッションをカプセル化したものです。つまり、メソッド呼び出しはストリームです。

送信ロジック (トランスポート パック) は、実際の基礎となる IO データ送信と対応するイベント リスナーの構築を担当します。

サービス管理 (Server Pack) は、論理サービス ServerImpl と監視サービス NettyServer の構築と起動を担当します。これはサーバー ロジック全体の関数ファクトリです。

サービス呼び出しの原則

サービスコール方法

  • 一般的な RPC 呼び出しモード、つまり要求/応答モード。

  • HTTP/2.0に基づくストリーミング呼び出し方式。

通常のコール - 同期ブロッキングコール

コード

BlockingStub = GreeterGrpc.newBlockingStub(チャネル);

...

HelloRequest リクエスト = HelloRequest.newBuilder().setName(name).build();

HelloReply 応答。

試す {

応答 = ブロッキングStub.sayHello(リクエスト);

...

原理

同期サービス コールは、フレームワーク層で gRPC フレームワークの ClientCalls によってカプセル化されます。サービス コールが非同期的に開始された後、呼び出し元のスレッドは、応答が受信されるまで同期的にブロックされ、その後、ブロックされたビジネス スレッドが起動されます。

 

将来ベースの非同期 RPC 呼び出し

コード

HelloRequest リクエスト = HelloRequest.newBuilder().setName(name).build();

試す {

com.google.common.util.concurrent.ListenableFuture<io.grpc.examples.helloworld.HelloReply>

listenableFuture = futureStub.sayHello(リクエスト);

Futures.addCallback(listenableFuture, new FutureCallback<HelloReply>() {

@オーバーライド

public void onSuccess(@Nullable HelloReply 結果) {

logger.info("挨拶: " + result.getMessage());

}

原理

ListenableFuture を gRPC の Future リストに追加し、新しい FutureCallback オブジェクトを作成します。ListenableFuture が応答を取得すると、gRPC の DirectExecutor スレッド プールは新しく作成された FutureCallback を呼び出して onSuccess または onFailure を実行し、非同期コールバック通知を実装します。

 

リアクティブ スタイルの非同期 RPC 呼び出し

コード

HelloRequest リクエスト = HelloRequest.newBuilder().setName(name).build();

io.grpc.stub.StreamObserver<io.grpc.examples.helloworld.HelloReply> responseObserver =

新しい io.grpc.stub.StreamObserver<io.grpc.examples.helloworld.HelloReply>()

{

public void onNext(HelloReply 値)

{

logger.info("挨拶: " + value.getMessage());

}

public void onError(Throwable t){

logger.warning(t.getMessage());

}

public void onCompleted(){}

};

stub.sayHello(request,responseObserver);

原理

 

応答 StreamObserver を入力パラメーターとして非同期サービス呼び出しに渡すと、メソッドは空を返し、プログラムは現在のビジネス スレッドをブロックせずに下方向に実行を続けます。

ストリーミングモードサービスコール

  • サーバーストリーミング

  • クライアントストリーミング

  • サーバーとクライアント間の双方向ストリーミング

サーバーストリーミング

コード

rpc ListFeature(Rectangle) は (ストリーム機能) {} を返します

public void listFeature(io.grpc.examples.routeguide.Rectangle request,

io.grpc.stub.StreamObserver<io.grpc.examples.routeguide.Feature> responseObserver) {

asyncUnimplementedUnaryCall(METHOD_LIST_FEATURES、responseObserver);

}

原理

 

io.grpc.stub.StreamObserver responseObserver を構築し、その 3 つのコールバック インターフェイスを実装します。これはサーバー側ストリーミング モードであるため、その onNext(Feature value) が複数回コールバックされ、それぞれが応答を表すことに注意してください。返されると、onCompleted() メソッドが呼び出されます。

クライアントストリーミング

コード

rpc RecordRoute(stream Point) は (Routesummary) {} を返します

StreamObserver<Point> requestObserver = asyncStub.recordRoute(responseObserver);

試す {

// 特徴リストからランダムに選択された numPoints ポイントを送信します。

for (int i = 0; i < numPoints; ++i) {

int インデックス = ランダム.nextInt(features.size());

ポイント point = features.get(index).getLocation();

info("訪問ポイント {0}, {1}", RouteGuideUtil.getLatitude(point),

RouteGuideUtil.getLongitude(point));

requestObserver.onNext(ポイント);

原理

 

非同期サービス呼び出しは、リクエスト StreamObserver オブジェクトを取得し、ループ内で requestObserver.onNext(point) を呼び出し、リクエスト メッセージをサーバーに非同期に送信します。送信が完了したら、requestObserver.onCompleted() を呼び出して、すべてのリクエストがサーバーに通知されます。が送信され、サーバーからの応答を受信できるようになります。

双方向ストリーミング

コード

rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}

StreamObserver<RouteNote> requestObserver =

asyncStub.routeChat(new StreamObserver<RouteNote>() {

@オーバーライド

public void onNext(RouteNote note) {

info("{1}、{2} でメッセージ \"{0}\" を受信しました", note.getMessage(), note.getLocation()

.getLatitude()、note.getLocation().getLongitude());

if (testHelper != null) {

testHelper.onMessage(note);

}

}

//複数のリクエストを送信する

for (RouteNote リクエスト : リクエスト) {

info("メッセージ \"{0}\" を {1}、{2} に送信中", request.getMessage(), request.getLocation()

.getLatitude()、request.getLocation().getLongitude());

requestObserver.onNext(リクエスト);

}

} catch (RuntimeException e) {

// RPCをキャンセルする

requestObserver.onError(e);

eを投げます。

}

// リクエストの終了をマークします

requestObserver.onCompleted();

原理

 

ストリーミング応答オブジェクト StreamObserver を構築し、onNext などのインターフェイスを実装します。サーバーもストリーミング モードであるため、複数の応答があり、onNext が複数回呼び出されることになります。

ループ内で requestObserver の onNext メソッドを呼び出してリクエスト メッセージを送信します。

おすすめ

転載: blog.csdn.net/qq_29857681/article/details/126229434