サービス検出
サービス検出は、サービス同士が互いを見つけるための仕組みです。http://localhost:5001 のような URL をハードコーディングする代わりに、フロントエンドは catalog サービスを名前で参照するだけで、実際のアドレス解決は Aspire が担当します。
サービス検出の仕組み
Section titled “サービス検出の仕組み”WithReference() を使ってサービスを接続すると、Aspire は自動的にサービス検出を構成します。
- AppHost がリソースを宣言 してエンドポイントを割り当てる
- 構成が注入される 各サービスに環境変数経由で構成が渡される
- コードは論理名を使用
https+http://catalogのような論理名を使う - Aspire のリゾルバーが解決 実行時に論理名を実アドレスへ変換する
重要なポイント: コードでは catalog のような論理サービス名を使い、Aspire の構成ベースのエンドポイント リゾルバーが実行時に実アドレスへ変換します。
参照による暗黙的なサービス検出
Section titled “参照による暗黙的なサービス検出”サービス検出用の構成は、あるプロジェクトから参照されているサービスに対してのみ追加されます。たとえば、次の AppHost プログラムを見てみましょう。
var builder = DistributedApplication.CreateBuilder(args);
var catalog = builder.AddProject<Projects.CatalogService>("catalog");var basket = builder.AddProject<Projects.BasketService>("basket");
var frontend = builder.AddProject<Projects.MyFrontend>("frontend") .WithReference(basket) .WithReference(catalog);この例では、frontend プロジェクトが catalog プロジェクトと basket プロジェクトを参照しています。2 つの WithReference 呼び出しは、Aspire に次のことを指示します。
- 構成を注入する:
catalogとbasketのサービス検出情報をfrontendに渡す - 解決を有効にする:
frontendでhttps+http://catalogのような URI をHttpClientから利用できるようにする
名前付きエンドポイント
Section titled “名前付きエンドポイント”一部のサービスは、複数の「名前付きエンドポイント」を公開します。名前付きエンドポイントは、HTTP リクエスト URI のホスト部分にエンドポイント名を指定することで解決できます。形式は scheme://_endpointName.serviceName です。たとえば、「basket」という名前のサービスが「dashboard」というエンドポイントを公開している場合、https+http://_dashboard.basket という URI でそのエンドポイントを指定できます:
builder.Services.AddHttpClient<BasketServiceClient>( static client => client.BaseAddress = new("https+http://basket"));
builder.Services.AddHttpClient<BasketServiceDashboardClient>( static client => client.BaseAddress = new("https+http://_dashboard.basket"));この例では、basket サービス用と、basket サービスのダッシュボード用の 2 つの HttpClient クラスが追加されています。
構成を使用した名前付きエンドポイント
Section titled “構成を使用した名前付きエンドポイント”構成ベースのエンドポイント リゾルバーを使用すると、エンドポイント名の前に _endpointName を付けることで、構成内に名前付きエンドポイントを指定できます。ここで endpointName はエンドポイント名です。たとえば、次の appsettings.json では、名前なしの既定エンドポイントと、「dashboard」という名前のエンドポイントが定義されています:
{ "Services": { "basket": { "https": "https://10.2.3.4:8080" /* https://basket で要求される HTTPS エンドポイント */, "dashboard": "https://10.2.3.4:9999" /* https://_dashboard.basket で要求される "dashboard" エンドポイント */ } }}この JSON では、次のように解決されます:
- 既定エンドポイントとして
https://basketを解決すると10.2.3.4:8080になります。 https://_dashboard.basketで解決される「dashboard」エンドポイントは10.2.3.4:9999になります。
Aspire における名前付きエンドポイント
Section titled “Aspire における名前付きエンドポイント”名前付きエンドポイントは、AppHost のコードから公開することもできます。たとえば、先ほどの例は次のように表現できます。
var basket = builder.AddProject<Projects.BasketService>("basket") .WithHttpsEndpoint(port: 9999, name: "dashboard");DNS SRV を使用した Kubernetes 上の名前付きエンドポイント
Section titled “DNS SRV を使用した Kubernetes 上の名前付きエンドポイント”Kubernetes にデプロイする場合、DNS SRV サービス エンドポイント リゾルバーを使用して名前付きエンドポイントを解決できます。たとえば、次のリソース定義では、「basket」というサービスに対して、「default」と「dashboard」という 2 つのエンドポイント用の DNS SRV レコードが作成されます。
apiVersion: v1kind: Servicemetadata: name: basketspec: selector: name: basket-service clusterIP: None ports: - name: default port: 8080 - name: dashboard port: 9999「basket」サービスの「dashboard」エンドポイントを解決するように構成するには、次のように DNS SRV サービス エンドポイント リゾルバーをホスト ビルダーに追加します。
builder.Services.AddServiceDiscoveryCore();builder.Services.AddDnsSrvServiceEndpointProvider();詳しくは、AddServiceDiscoveryCore および AddDnsSrvServiceEndpointProvider をご参照ください。
特別なポート名である「default」は、https://basket という URI で解決される既定のエンドポイントを指定するために使われます。
先ほどと同様に、バスケット サービス用の HttpClient にサービス ディスカバリーを追加するには、次のようにします:
builder.Services.AddHttpClient<BasketServiceClient>( static client => client.BaseAddress = new("https://basket"));同様に、「dashboard」エンドポイントは次のように指定できます。
builder.Services.AddHttpClient<BasketServiceDashboardClient>( static client => client.BaseAddress = new("https://_dashboard.basket"));トラブルシューティング
Section titled “トラブルシューティング”サービスが見つからない / “No endpoints resolved”
Section titled “サービスが見つからない / “No endpoints resolved””症状: HttpClient が “No endpoints resolved for service ‘myservice’” のような例外を投げる、または接続拒否が発生する。
よくある原因:
WithReference()の不足: 呼び出し元サービスが AppHost で対象サービスに接続されていない- サービス名の不一致: URI 内の名前が
AddProject()またはAddContainer()の名前と一致していない - サービス未起動: 対象サービスが起動に失敗している、または起動中である
対処方法: AppHost でサービス同士が接続されていることを確認します。
var api = builder.AddProject<Projects.Api>("api");var frontend = builder.AddProject<Projects.Frontend>("frontend") .WithReference(api); // ← これが必要です名前付きエンドポイントを解決できない
Section titled “名前付きエンドポイントを解決できない”症状: https://_endpointName.serviceName を使うとエラーになる。
対処方法: AppHost でそのエンドポイントに名前が設定されていることを確認します。
var api = builder.AddProject<Projects.Api>("api") .WithHttpEndpoint(port: 9999, name: "dashboard"); // ← 名前を一致させる次に、アンダースコア付きプレフィックスで正確に指定します。
client.BaseAddress = new("https://_dashboard.api");URI 形式を理解する
Section titled “URI 形式を理解する”https+http:// プレフィックスは「HTTPS を優先し、失敗時は HTTP にフォールバックする」ことを意味します。
| URI 形式 | 意味 |
|---|---|
https://catalog | 既定エンドポイントへ HTTPS のみで接続 |
http://catalog | 既定エンドポイントへ HTTP のみで接続 |
https+http://catalog | HTTPS を優先し、HTTP にフォールバック |
https://_admin.catalog | 名前付き “admin” エンドポイントへ HTTPS で接続 |