--- lang: ja-jp breaks: true --- # ASP.NET Core gRPC の基礎 2021-09-13 > .NET の gRPC の概要 > https://docs.microsoft.com/ja-jp/aspnet/core/grpc/ :::warning ASP.NET Core gRPC には、Azure App Service または IIS と共に使用するための追加の要件があります。 gRPCを使用できる場所の詳細については、「.NET での gRPC でサポートされているプラットフォーム」を参照してください。 > .NET での gRPC でサポートされているプラットフォーム > Azure サービス > Azure App Service では、HTTP/2 による gRPC のホストがサポートされていません。 gRPC-Web は互換性のある代替手段です。 ::: ## gRPC クライアントを構成する https://docs.microsoft.com/ja-jp/aspnet/core/grpc/client ```csharp= var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new Greet.GreeterClient(channel); ``` チャネルは、gRPC サービスへの有効期限が長い接続を表します。 ## クライアント パフォーマンス https://docs.microsoft.com/ja-jp/aspnet/core/grpc/client * チャネルの作成は、**コストのかかる操作**となる場合があります。 チャネルを gRPC 呼び出しのために**再利用すると、パフォーマンス上のメリットがあります**。 * gRPC クライアントはチャネルを使用して作成されます。 gRPC クライアントは軽量なオブジェクトであり、キャッシュしたり**再利用したりする必要はありません**。 * 異なる種類のクライアントを含め、1 つチャネルから複数の gRPC クライアントを作成できます。 * チャネルおよびそのチャネルから作成されたクライアントは、**複数のスレッドで安全に使用できます**。 * チャネルから作成されたクライアントは、**複数の同時呼び出しを行えます**。 ASP.NET Core アプリから gRPC サービスを呼び出そうとしている場合は、gRPC クライアント ファクトリの統合を検討してください。 gRPC と HttpClientFactory の統合により、gRPC クライアントを一元的に作成する別の方法が得られます。 :::warning 現在のところ、Grpc.Net.Client による HTTP/2 を介した gRPC の呼び出しは、Xamarin ではサポートされていません。 将来の Xamarin のリリースで HTTP/2 のサポートを向上させるために作業を進めています。 Grpc.Core と gRPC-Web は、現在でも機能する実行可能な代替手段です。 ::: ## 期限の構成 gRPC 呼び出しの期限を設定するには、`CallOptions.Deadline` を構成します。 ```csharp= var client = new Greet.GreeterClient(channel); try { var response = await client.SayHelloAsync( new HelloRequest { Name = "World" }, deadline: DateTime.UtcNow.AddSeconds(5)); // Greeting: Hello World Console.WriteLine("Greeting: " + response.Message); } catch (RpcException ex) when (ex.StatusCode == StatusCode.DeadlineExceeded) { Console.WriteLine("Greeting timeout."); } ``` ## gRPC メソッドで HttpContext を解決する https://docs.microsoft.com/ja-jp/aspnet/core/grpc/aspnetcore gRPC API は、メソッド、ホスト、ヘッダー、トレーラーなど、一部の HTTP/2 メッセージ データへのアクセスを提供します。 アクセスには、各 gRPC メソッドに渡される `ServerCallContext` 引数が使用されます。 ```csharp= public class GreeterService : Greeter.GreeterBase { public override Task<HelloReply> SayHello( HelloRequest request, ServerCallContext context) { return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); } } ``` `GetHttpContext` 拡張メソッドを使用すると、ASP.NET API で基となる HTTP/2 メッセージを表す `HttpContext` にフル アクセスできます。 ```csharp= public class GreeterService : Greeter.GreeterBase { public override Task<HelloReply> SayHello( HelloRequest request, ServerCallContext context) { var httpContext = context.GetHttpContext(); var clientCertificate = httpContext.Connection.ClientCertificate; return Task.FromResult(new HelloReply { Message = "Hello " + request.Name + " from " + clientCertificate.Issuer }); } } ``` ## サービス オプションを構成する https://docs.microsoft.com/ja-jp/aspnet/core/grpc/configuration #### MaxSendMessageSize サーバーから送信できる最大メッセージ サイズ (バイト単位)。 構成された最大メッセージ サイズを超えるメッセージを送信しようとすると、例外が発生します。 null に設定する場合、メッセージ サイズは制限されません。 #### MaxReceiveMessageSize サーバーで受信できる最大メッセージ サイズ (バイト単位)。 サーバーでこの制限を超えるメッセージを受信すると、例外がスローされます。 この値を大きくすると、サーバーはより大きなメッセージを受け取れますが、メモリの消費に悪影響を与える可能性があります。 null に設定する場合、メッセージ サイズは制限されません。 #### EnableDetailedErrors `true` の場合、サービス メソッドで例外がスローされると、詳細な例外メッセージがクライアントに返されます。 既定値は、false です。 EnableDetailedErrors を true に設定すると、機密情報が漏洩する可能性があります。 #### CompressionProviders メッセージの圧縮と圧縮解除に使用される圧縮プロバイダーのコレクション。 カスタム圧縮プロバイダーを作成し、コレクションに追加することができます。 既定で構成されているプロバイダーは、gzip 圧縮をサポートしています。 #### ResponseCompressionAlgorithm サーバーから送信されるメッセージの圧縮に使用される圧縮アルゴリズム。 このアルゴリズムは、`CompressionProviders` の圧縮プロバイダーと一致している必要があります。 アルゴリズムで応答を圧縮するには、そのアルゴリズムをサポートしていることをクライアントが `grpc-accept-encoding` ヘッダーで送信することによって、そのことを示す必要があります。 #### ResponseCompressionLevel サーバーから送信されるメッセージの圧縮に使用される圧縮レベル。 #### Interceptors 各 gRPC 呼び出しで実行されるインターセプターのコレクション。 インターセプターは、登録されている順序で実行されます。 グローバルに構成されたインターセプターは、1 つのサービスに対してインターセプターが構成される前に実行されます。 gRPC インターセプターの詳細については、「gRPC インターセプターとミドルウェア」を参照してください。 #### IgnoreUnknownServices `true` の場合、不明なサービスおよびメソッドへの呼び出しでは `UNIMPLEMENTED` 状態は返されず、要求は `ASP.NET Core` に登録された次のミドルウェアに渡されます。 #### 構成方法 Startup.ConfigureServices の AddGrpc 呼び出しに対して options デリゲートを指定することで、すべてのサービスに対してオプションを構成できます。 ```csharp= public void ConfigureServices(IServiceCollection services) { services.AddGrpc(options => { options.EnableDetailedErrors = true; options.MaxReceiveMessageSize = 2 * 1024 * 1024; // 2 MB options.MaxSendMessageSize = 5 * 1024 * 1024; // 5 MB }); } ``` 1 つのサービスのオプションは、`AddGrpc` で提供されるグローバル オプションをオーバーライドします。また、`AddServiceOptions<TService>` を使用して構成することができます。 ```csharp= public void ConfigureServices(IServiceCollection services) { services.AddGrpc().AddServiceOptions<MyService>(options => { options.MaxReceiveMessageSize = 2 * 1024 * 1024; // 2 MB options.MaxSendMessageSize = 5 * 1024 * 1024; // 5 MB }); } ``` ## クライアント オプションを構成する https://docs.microsoft.com/ja-jp/aspnet/core/grpc/configuration #### HttpHandler gRPC 呼び出しを行うために使用される `HttpMessageHandler`。 カスタム `HttpClientHandler` を構成したり、gRPC 呼び出しの HTTP パイプラインに追加のハンドラーを加えたりするために、クライアントを設定できます。`HttpMessageHandler` が指定されていない場合、自動廃棄のチャネルのために新しい `HttpClientHandler` インスタンスが作成されます。 #### HttpClient gRPC 呼び出しを行うために使用される HttpClient。 この設定は、`HttpHandler` に代わる方法です。 #### DisposeHttpClient `true` に設定し、`HttpMessageHandler` または `HttpClient` が指定されている場合、`GrpcChannel` が廃棄されたときに (該当する) `HttpHandler` または `HttpClient` が廃棄されます。 #### LoggerFactory gRPC 呼び出しに関する情報をログに記録するため、クライアントによって使用される `LoggerFactory`。 `LoggerFactory` インスタンスは、依存関係の挿入から解決することも、`LoggerFactory.Create` を使用して作成することもできます。 ログ記録を構成する例については、「.NET での gRPC のログ記録と診断」を参照してください。 #### MaxSendMessageSize クライアントから送信できる最大メッセージ サイズ (バイト単位)。 構成された最大メッセージ サイズを超えるメッセージを送信しようとすると、例外が発生します。 null に設定する場合、メッセージ サイズは制限されません。 #### MaxReceiveMessageSize クライアントで受信できる最大メッセージ サイズ (バイト単位)。 クライアントでこの制限を超えるメッセージを受信すると、例外がスローされます。 この値を大きくすると、クライアントはより大きなメッセージを受け取れますが、メモリの消費に悪影響を与える可能性があります。 null に設定する場合、メッセージ サイズは制限されません。 #### Credentials `ChannelCredentials` のインスタンス。 資格情報は、認証メタデータを gRPC 呼び出しに追加するために使用します。 #### CompressionProviders メッセージの圧縮と圧縮解除に使用される圧縮プロバイダーのコレクション。 カスタム圧縮プロバイダーを作成し、コレクションに追加することができます。 既定で構成されているプロバイダーは、gzip 圧縮をサポートしています。 #### ThrowOperationCanceledOnCancellation `true` に設定されている場合、呼び出しが取り消されたとき、または期限を超えたときに、クライアントから `OperationCanceledException` がスローされます。 #### MaxRetryAttempts 最大再試行回数。 サービス構成で指定されている再試行回数と `Hedging` 試行回数が、この値によって制限されます。この値のみを設定しても、再試行は行われません。 再試行は、サービス構成で有効となり、`ServiceConfig` を使用して実行されます。 null 値を指定すると、最大再試行回数の制限が解除されます。 再試行の詳細については、「gRPC の再試行による一時的障害の処理」を参照してください。 #### MaxRetryBufferSize 再試行、または `Hedging` 呼び出しを実行するときに、送信済みメッセージを格納するために使用することができる、バイト単位の最大バッファー サイズ。 バッファーの制限を超過した場合、再試行はそれ以上実行されず、すべての `Hedging` 呼び出しは 1 回を除いてすべてキャンセルされます。 この制限は、チャネルを使用して実行されるすべての呼び出しに対して適用されます。 null 値を指定すると、再試行の最大バッファー サイズの制限が解除されます。 #### MaxRetryBufferPerCallSize 再試行、または `Hedging` 呼び出しを実行するときに、送信済みメッセージを格納するために使用することができる、バイト単位の最大バッファー サイズ。 バッファーの制限を超過した場合、再試行はそれ以上実行されず、すべての `Hedging` 呼び出しは 1 回を除いてすべてキャンセルされます。 この制限は、1 回の呼び出しに適用されます。 null 値を指定すると、呼び出し 1 回あたりの、再試行の最大バッファー サイズの制限が解除されます。 #### ServiceConfig gRPC チャネルのサービス構成。 サービス構成を使用すると、gRPC の再試行を構成することができます。 #### 構成方法 ```csharp= static async Task Main(string[] args) { var channel = GrpcChannel.ForAddress( "https://localhost:5001", new GrpcChannelOptions { MaxReceiveMessageSize = 5 * 1024 * 1024, // 5 MB MaxSendMessageSize = 2 * 1024 * 1024 // 2 MB }); var client = new Greeter.GreeterClient(channel); var reply = await client.SayHelloAsync( new HelloRequest { Name = "GreeterClient" }); Console.WriteLine("Greeting: " + reply.Message); } ``` ## gRPC を使用したパフォーマンスのベスト プラクティス https://docs.microsoft.com/ja-jp/aspnet/core/grpc/performance #### gRPC チャネルを再利用する #### 接続の同時実行 #### 負荷分散 #### クライアント側の負荷分散 #### プロキシの負荷分散 #### プロセス間通信 #### キープ アライブ ping #### ストリーム #### バイナリ ペイロード Protobuf は、オーバーヘッドを最小限に抑えて、大きなバイナリ ペイロードを効率的にシリアル化するバイナリ形式です。 JSON のようなテキストベースの形式では、base64 へのバイトのエンコードが必要で、メッセージ サイズが 33% 追加されます。 #### バイナリ ペイロードの送信 `UnsafeByteOperations.UnsafeWrap(ReadOnlyMemory<byte> bytes)` を使用して ByteString インスタンスを作成すると、追加の割り当てとコピーを回避できます。 ByteString の使用中に変更が行われないように、UnsafeByteOperations.UnsafeWrap を使用してもバイトはコピーされません。 :::info UnsafeByteOperations.UnsafeWrap には、Google.Protobuf バージョン 3.15.0 以降が必要です。 ::: #### バイナリ ペイロードの読み取り ## WCF 開発者向け ASP.NET Core gRPC https://docs.microsoft.com/ja-jp/dotnet/architecture/grpc-for-wcf-developers/ ## Protobuf のバリアント型の Any フィールドと OneOf フィールド https://docs.microsoft.com/ja-jp/dotnet/architecture/grpc-for-wcf-developers/protobuf-any-oneof プロトコル バッファー (Protobuf) には、複数の型の値を処理するための 2 つの簡単なオプションが用意されています。 Any 型では、任意の既知の Protobuf メッセージ型を表すことができます。 また、oneof キーワードを使用すると、ある範囲のフィールドのうちの 1 つだけをメッセージで設定できることを指定できます。 #### Any #### Oneof ## gRPC を使用したプロセス間通信 https://docs.microsoft.com/ja-jp/aspnet/core/grpc/interprocess クライアントとサービスが同じマシン上にある場合は、プロセス間通信 (IPC) の方が TCP より効率的です。 gRPCにカスタム トランスポートを適用することで プロセス間通信 が可能となります。 ## gRPC から JSON Web API を作成する https://docs.microsoft.com/ja-jp/aspnet/core/grpc/httpapi ## .NET を使用したコードファーストの gRPC サービスとクライアント https://docs.microsoft.com/ja-jp/aspnet/core/grpc/code-first コードファースト gRPC では、.NET の型を使用して、サービスとメッセージ コントラクトを定義します。 コードファーストは、システム全体で .NET を使用する場合に適しています。 .Net サービスとデータ コントラクトの型は、.NET サーバーとクライアントの間で共有できます。 .proto ファイルおよびコード生成でコントラクトを定義する必要がなくなります。 複数の言語の多言語システムでは、コードファーストはお勧めできません。 .NET サービスとデータ コントラクトの型は、.NET 以外のプラットフォームでは使用できません。 コードファーストを使用して作成された gRPC サービスを呼び出すには、他のプラットフォームでサービスと一致する .proto コントラクトを作成する必要があります。 #### protobuf-net.Grpc https://protobuf-net.github.io/protobuf-net.Grpc/ AspNetCore.Docs/aspnetcore/grpc/code-first/samples/5.x/ https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/grpc/code-first/samples/5.x ## コードファースト gRPC サービスを作成する https://docs.microsoft.com/ja-jp/aspnet/core/grpc/code-first ## コードファースト gRPC クライアントを作成する https://docs.microsoft.com/ja-jp/aspnet/core/grpc/code-first ## Windows Communication Foundation (WCF) 開発者向けの gRPC https://docs.microsoft.com/ja-jp/aspnet/core/grpc/why-migrate-wcf-to-dotnet-grpc ## WCFの `OperationContract` で指定される `IsOneWay` プロパティに該当する機能 > WCF エンドポイントと gRPC メソッド > https://docs.microsoft.com/ja-jp/dotnet/architecture/grpc-for-wcf-developers/wcf-endpoints-grpc-methods ### IsOneWay 一方向の gRPC メソッドでは、Empty の結果が返されるか、クライアント ストリーミングが使用されます。 > WCF の一方向操作と gRPC のクライアント ストリーミング > https://docs.microsoft.com/ja-jp/dotnet/architecture/grpc-for-wcf-developers/rpc-types#wcf-one-way-operations-and-grpc-client-streaming > WCF によって提供される一方向の操作 (`[OperationContract(IsOneWay = true)]` でマークされているもの) からは、トランスポート固有の受信確認が返されます。 gRPC のサービス メソッドからは、空の場合でも、常に応答が返されます。 クライアントでは、常にその応答を待機する必要があります。 gRPC でのメッセージングの "ファイア アンド フォーゲット" スタイルの場合は、クライアント ストリーミング サービスを作成できます。 ###### tags: `gRPC` `ASP.NET Core` `基礎`
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.