Share via


.NET でのサービス検出

この記事では、Microsoft.Extensions.ServiceDiscovery ライブラリの使用方法について説明します。 サービス検出は、開発者が物理アドレス (IP アドレスとポート) の代わりに論理名を使って外部サービスを参照するための方法です。

作業の開始

.NET でサービス検出を使い始めるには、Microsoft.Extensions.ServiceDiscovery NuGet パッケージをインストールします。

dotnet add package Microsoft.Extensions.ServiceDiscovery --prerelease

詳しくは、「dotnet add package」または「.NET アプリケーションでパッケージの依存関係を管理する」をご覧ください。

使用例

プロジェクトの Program.cs ファイルで、AddServiceDiscovery 拡張メソッドを呼び出してサービス検出をホストに追加し、既定のサービス エンドポイント リゾルバーを構成します。

builder.Services.AddServiceDiscovery();

AddServiceDiscovery 拡張メソッドを呼び出して、個々の IHttpClientBuilder にサービス検出を追加します。

builder.Services.AddHttpClient<CatalogServiceClient>(static client =>
    {
        client.BaseAddress = new("https://catalog");
    })
    .AddServiceDiscovery();

または、既定ですべての HttpClient インスタンスにサービス検出を追加することもできます。

builder.Services.ConfigureHttpClientDefaults(static http =>
{
    // Turn on service discovery by default
    http.AddServiceDiscovery();
});

HTTP エンドポイントを解決する際のスキームの選択

サービスをローカルで開発およびテストするときには HTTP を使用し、そのサービスをデプロイするときには HTTPS を使用するのが一般的です。 サービス検出では、サービス検出に与えられる入力文字列で URI スキームの優先度リストを指定できるようにして、これをサポートしています。 サービス検出は、スキームのサービスの解決を順番に試行し、エンドポイントが見つかると停止します。 URI スキームは + 文字で区切られます (例: "https+http://basket")。 サービス検出は、まず "basket" サービスの HTTPS エンドポイントの検出を試み、次に HTTP エンドポイントにフォールバックします。 HTTPS エンドポイントが見つかると、サービス検出に HTTP エンドポイントは含まれません。

ServiceDiscoveryOptionsAllowedSchemes プロパティと AllowAllSchemes プロパティを構成すると、スキームをフィルター処理できます。 すべてのスキームが許可されることを示すには、AllowAllSchemes プロパティを使用します。 既定では、AllowAllSchemestrue に設定され、すべてのスキームが許可されます。 AllowAllSchemesfalse に設定し、許可されるスキームを AllowedSchemes プロパティに追加すると、スキームを制限できます。 たとえば、HTTPS のみを許可するには、次のようにします。

services.Configure<ServiceDiscoveryOptions>(options =>
{
    options.AllowAllSchemes = false;
    options.AllowedSchemes = ["https"];
});

すべてのスキームを明示的に許可するには、ServiceDiscoveryOptions.AllowAllSchemes プロパティを true に設定します。

services.Configure<ServiceDiscoveryOptions>(
    options => options.AllowAllSchemes = true);

構成からサービス エンドポイントを解決する

AddServiceDiscovery 拡張メソッドは、既定で構成ベースのエンドポイント リゾルバーを追加します。 このリゾルバーは、.NET 構成システムからエンドポイントを読み取ります。 このライブラリでは、appsettings.json、環境変数、または他の任意の IConfiguration ソースからの構成がサポートされています。

次に示すのは、appsettings.json を使って catalog という名前のサービスのエンドポイントを構成する方法の例です。

{
  "Services": {
    "catalog": {
      "https": [
        "localhost:8080",
        "10.46.24.90:80"
      ]
    }
  }
}

前の例では、catalog という名前のサービスに対して、https://localhost:8080"https://10.46.24.90:80" の 2 つのエンドポイントが追加されます。 catalog が解決されるたびに、これらのエンドポイントのいずれかが選ばれます。

IServiceCollectionAddServiceDiscoveryCore 拡張メソッドを使ってサービス検出をホストに追加した場合は、IServiceCollectionAddConfigurationServiceEndpointProvider 拡張メソッドを呼び出すことにより、構成ベースのエンドポイント リゾルバーを追加できます。

構成

構成リゾルバーを構成するには、次の構成オプションを備える ConfigurationServiceEndpointProviderOptions クラスを使います。

  • SectionName: サービス エンドポイントを含む構成セクションの名前。 既定値は "Services" です。

  • ApplyHostNameMetadata: 解決されたエンドポイントにホスト名メタデータを適用するかどうかを決定するために使われるデリゲート。 既定では、false を返す関数です。

これらのオプションを構成するには、アプリケーションの Startup クラスまたは Program ファイル内の IServiceCollectionConfigure 拡張メソッドを使用できます。

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<ConfigurationServiceEndPointResolverOptions>(
    static options =>
    {
        options.SectionName = "MyServiceEndpoints";

        // Configure the logic for applying host name metadata
        options.ApplyHostNameMetadata = static endpoint =>
        {
            // Your custom logic here. For example:
            return endpoint.EndPoint is DnsEndPoint dnsEp
                && dnsEp.Host.StartsWith("internal");
        };
    });

前に示した例では、サービス エンドポイントに対してカスタム セクション名を設定し、ホスト名メタデータを適用するためのカスタム条件ロジックを提供しています。

プラットフォーム提供のサービス検出を使用してサービス エンドポイントを解決する

Azure Container Apps や Kubernetes (適切に構成されている場合) などの特定のプラットフォームでは、サービス検出クライアント ライブラリを必要とせずにサービス検出機能が提供されます。 そのような環境にアプリケーションがデプロイされている場合は、プラットフォームの組み込み機能を使うと便利です。 パススルー リゾルバーは、このシナリオを容易にするように設計されています。 それを使うと、開発者のコンピューターなどのさまざまな環境で、構成などの代替リゾルバーを利用できます。 重要なのは、この柔軟性を実現するために、コードの変更や条件付きガードの実装が必要ないことです。

パススルー リゾルバーは外部解決を実行せず、代わりに、DnsEndPoint と表される入力サービス名を返すことによってエンドポイントを解決します。

パススルー プロバイダーは、AddServiceDiscovery 拡張メソッドを使ってサービス検出を追加すると、既定で構成されます。

IServiceCollectionAddServiceDiscoveryCore 拡張メソッドを使ってサービス検出をホストに追加した場合は、IServiceCollectionAddPassThroughServiceEndpointProvider 拡張メソッドを呼び出すことにより、パススルー プロバイダーを追加できます。

関連項目