Microsoft.Extensions.ServiceDiscovery 8.1.0

前缀已预留
dotnet add package Microsoft.Extensions.ServiceDiscovery --version 8.1.0                
NuGet\Install-Package Microsoft.Extensions.ServiceDiscovery -Version 8.1.0                
此命令旨在在 Visual Studio 的包管理器控制台中使用,因为它使用了 NuGet 模块的Install-Package版本。
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="8.1.0" />                
对于支持PackageReference的项目,将该 XML 节点复制到项目文件中以引用该包。
paket add Microsoft.Extensions.ServiceDiscovery --version 8.1.0                
#r "nuget: Microsoft.Extensions.ServiceDiscovery, 8.1.0"                
#r 指令可用于 F# Interactive 和 Polyglot Notebooks。将其复制到交互式工具或脚本的源代码中以引用此包。
// Install Microsoft.Extensions.ServiceDiscovery as a Cake Addin
#addin nuget:?package=Microsoft.Extensions.ServiceDiscovery&version=8.1.0

// Install Microsoft.Extensions.ServiceDiscovery as a Cake Tool
#tool nuget:?package=Microsoft.Extensions.ServiceDiscovery&version=8.1.0                

Microsoft.Extensions.ServiceDiscovery

Microsoft.Extensions.ServiceDiscovery 库旨在简化 .NET 应用程序中服务发现模式的集成。服务发现是大多数分布式系统和微服务架构的关键组件。此库提供了一种简单的方法来将服务名称解析为端点地址。

在典型系统中,服务配置会随着时间的推移而改变。服务发现通过监控端点配置(当支持时使用基于推送的通知,在其他情况下回退到轮询)来处理这种改变。当端点刷新时,调用者将收到通知,以便他们可以观察刷新的结果。

工作原理

服务发现使用配置的提供者来解析服务端点。当服务端点解析完成时,每个注册的提供者将按注册顺序被调用,以贡献到一组服务端点(ServiceEndpointSource的一个实例)。

提供者实现了IServiceEndpointProvider接口。它们由IServiceEndpointProviderProvider的实例创建,该实例用.NET 依赖注入系统注册。

开发人员通常使用IHttpClientFactoryAddServiceDiscovery扩展方法将服务发现添加到他们的HttpClient中,具体操作可参考HttpClient的相关文档。

可以直接通过调用ServiceEndpointResolverGetEndpointsAsync方法来解析服务,该方法返回一个解析后的端点集合。

变更通知

随着时间推移,服务配置可能会发生变化。服务发现通过支持的基于推送的通知方式来监控端点配置,在不支持时则回退到轮询方式。当端点更新时,调用者会收到通知,以便可以观察新结果。要订阅通知,调用者可以使用ServiceEndpointCollectionChangeToken属性。有关变更令牌的更多信息,请参阅ASP.NET Core中的变更令牌检测更改

使用功能进行扩展

服务端点(ServiceEndpoint实例)和服务端点集合(ServiceEndpointCollection实例)通过它们的Features属性提供了一个可扩展的IFeatureCollection。功能作为接口暴露在功能集合上。提供商可以在解析时间添加、修改、包装、替换甚至删除这些接口。可能存在于ServiceEndpoint中的功能包括:

解析顺序

Microsoft.Extensions.ServiceDiscovery系列包中包含的提供商在调用时,如果集合中已存在端点,则跳过解析。例如,假设已注册以下提供商:配置DNS SRV直接通过。在解析发生时,将按顺序调用提供商。如果配置提供商没有发现任何端点,DNS SRV提供商将执行解析并可能添加一个或多个端点。如果DNS SRV提供商将端点添加到集合中,则直接通过提供商将跳过其解析并立即返回。

入门指南

安装

要安装库,请使用以下NuGet命令

dotnet add package Microsoft.Extensions.ServiceDiscovery

使用示例

在项目的Program.cs文件中,调用AddServiceDiscovery扩展方法以将服务发现添加到主机并配置默认服务端点提供者。

builder.Services.AddServiceDiscovery();

通过调用AddServiceDiscovery扩展方法将服务发现添加到单个IHttpClientBuilder

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

或者,您可以将服务发现添加到默认的HttpClient实例中

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

从配置中解析服务端点

AddServiceDiscovery扩展方法默认添加基于配置的端点提供者。该提供者从.NET 配置系统中读取端点。库支持通过appsettings.json、环境变量或任何其他IConfiguration源进行配置。

以下是一个通过appsettings.json配置名为catalog的服务端点的示例

{
  "Services": {
    "catalog": {
      "https": [
        "https://127.0.0.1:8443",
        "https://10.46.24.90:443"
      ]
    }
  }
}

上述示例为名为catalog的服务添加了两个端点:https://127.0.0.1:8443"https://10.46.24.90:443"}。每次解析catalog时,将选择其中一个端点。

如果使用AddServiceDiscoveryCore扩展方法在IServiceCollection上添加了服务发现,则可以通过在IServiceCollection上调用AddConfigurationServiceEndpointProvider扩展方法来添加基于配置的端点提供者。

配置

配置提供程序使用 ConfigurationServiceEndpointProviderOptions 类进行配置,该类提供了以下配置选项:

  • SectionName:包含服务端点的配置部分的名称。默认为 "Services"

  • ShouldApplyHostNameMetadata:一个委托,用于确定是否将主机名元数据应用到解析后的端点。默认返回 false 的函数。

要配置这些选项,您可以在应用程序的启动类或主程序文件中,使用 IServiceCollectionConfigure 扩展方法。

var builder = WebApplication.CreateBuilder(args);

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

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

此示例展示了如何为服务端点设置一个自定义部分名称,并根据条件提供自定义逻辑来应用主机名元数据。

解析 HTTP(S) 端点时的方案选择

在本地开发和测试服务时通常使用 HTTP,而在服务部署时使用 HTTPS。服务发现支持通过允许在传递给服务发现的输入字符串中指定 URI 方案的优先级列表来实现这一点。服务发现将按照顺序尝试解析指定方案的方案,并在找到一个端点后停止。URI 方案由一个 + 字符分隔,例如:"https+http://basket"。服务发现将首先尝试寻找名为 "basket" 服务的 HTTPS 端点,然后回退到 HTTP 端点。如果找到任何 HTTPS 端点,则服务发现将不包括 HTTP 端点。可以通过在 ServiceDiscoveryOptions 上配置 AllowedSchemesAllowAllSchemes 属性来过滤方案。 AllowAllSchemes 属性用来指示允许所有方案。默认情况下,AllowAllSchemestrue,并允许所有方案。可以通过将 AllowAllSchemes 设置为 false 并将允许的方案添加到 AllowedSchemes 属性中来限制方案。

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

要显式允许所有方案,将 ServiceDiscoveryOptions.AllowAllSchemes 属性设置为 true

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

使用平台提供的服务发现解析服务端点

某些平台,如 Azure Container Apps 和 Kubernetes(如果已配置),提供服务发现的解决方案,无需使用服务发现客户端库。当一个应用程序被部署到这些环境之一时,可能更希望使用平台的现有功能。透传提供程序是为了支持这种情况而存在的,同时仍然允许在其他环境中(例如在开发者的机器上)使用其他提供程序(如配置),而无需进行代码更改或条件设置。

透传提供程序不执行任何外部解析,而是通过返回表示为 DnsEndPoint 的输入服务名称来解析端点。

透传提供程序在通过 AddServiceDiscovery 扩展方法添加服务发现时默认配置。

如果在主机上使用 IServiceCollection 上的 AddServiceDiscoveryCore 扩展方法添加了服务发现,可以通过调用 IServiceCollection 上的 AddPassThroughServiceEndpointProvider 扩展方法添加透传提供程序。

在 Azure Container Apps 的情况下,服务名称应该与应用程序名称匹配。例如,如果您有一个名为 "basket" 的服务,那么应该有名为 "basket" 的相应的 Azure Container App。

.NET Aspire 中的服务发现

.NET Aspire 包含在开发和测试时配置服务发现的解决方案。此功能通过提供与上述 .NET Aspire AppHost 项目中的 "基于配置的端点提供程序" 期望的配置格式兼容的配置来实现。

只有被指定项目引用的服务才会添加服务发现配置。例如,考虑以下 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);

在上面的示例中,前端项目参考了目录项目(catalog)和购物车项目(basket)。两个WithReference调用指示.NET Aspire应用将引用的项目(catalogbasket)的服务发现信息传递到前端项目。

命名端点

一些服务公开了多个命名端点。可以通过在HTTP请求URI的主机部分指定端点名称来解析命名端点,格式为scheme://_endpointName.serviceName。例如,如果名为“购物车”的服务公开了一个名为“仪表板”的端点,那么可以使用URI https+http://_dashboard.basket来指定此端点,例如

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"));

在上面的示例中,添加了两个HttpClient:一个用于核心购物车服务,另一个用于购物车服务的仪表板。

使用配置指定的命名端点

使用基于配置的端点提供商,可以通过在端点值前加上_endpointName.来在配置中指定命名端点,其中endpointName是端点名称。例如,考虑下面的appsettings.json配置,它定义了一个默认端点(没有名称)和一个名为“dashboard”的端点

{
  "Services": {
    "basket":
      "https": "https://10.2.3.4:8080", /* the https endpoint, requested via https://basket */
      "dashboard": "https://10.2.3.4:9999" /* the "dashboard" endpoint, requested via https://_dashboard.basket */
    }
  }
}

.NET Aspire中的命名端点

.NET Aspire在开发和测试时间使用基于配置的提供程序,提供了方便的API来配置命名端点,然后将其转换为目标服务的配置。例如

var builder = DistributedApplication.CreateBuilder(args);

var basket = builder.AddProject<Projects.BasketService>("basket")
    .WithEndpoint(hostPort: 9999, scheme: "https", name: "admin");

var adminDashboard = builder.AddProject<Projects.MyDashboardAggregator>("admin-dashboard")
       .WithReference(basket.GetEndpoint("admin"));

var frontend = builder.AddProject<Projects.Frontend>("frontend")
       .WithReference(basket);

在上面的示例中,“购物车”服务除了公开默认的“http”端点外,还公开了一个“admin”端点。此端点由“admin-dashboard”项目消费,而“前端”项目消费了“购物车”的所有端点。或者,“前端”项目可以仅通过使用GetEndpoint(string name)方法来消费“购物车”的默认“http”端点,例如以下示例


// The preceding code is the same as in the above sample

var frontend = builder.AddProject<Projects.Frontend>("frontend")
       .WithReference(basket.GetEndpoint("https"));

使用DNS SRV在Kubernetes中使用的命名端点

在部署到Kubernetes时,可以使用DNS SRV服务端点提供程序来解析命名端点。例如,以下资源定义将在名为“购物车”的服务上创建名为“default”和“dashboard”的端点的DNS SRV记录。

apiVersion: v1
kind: Service
metadata:
  name: basket
spec:
  selector:
    name: basket-service
  clusterIP: None
  ports:
  - name: default
    port: 8080
  - name: dashboard
    port: 8888

要配置一个服务以解析“购物车”服务上的“dashboard”端点,请按如下方式将DNS SRV服务端点提供程序添加到主机构建器中

builder.Services.AddServiceDiscoveryCore();
builder.Services.AddDnsSrvServiceEndpointProvider();

特殊端口号“default”用于指定默认端点,使用URI https://basket进行解析。

与上一个示例类似,向购物车服务的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"));

在Azure Container Apps中的命名端点

目前不支持将服务部署到Azure Container Apps的命名端点。

反馈 & 贡献

https://github.com/dotnet/aspire

产品 兼容的和额外的计算的目标框架版本。
.NET net8.0是兼容的。 net8.0-android已被计算。 net8.0-browser已被计算。 net8.0-ios已被计算。 net8.0-maccatalyst已被计算。 net8.0-macos已被计算。 net8.0-tvos已被计算。 net8.0-windows已被计算。
兼容的目标框架
包含的目标框架(在包中)
了解更多关于 目标框架.NET Standard

NuGet包 (18)

显示依赖于Microsoft.Extensions.ServiceDiscovery的前5个NuGet包

下载
Microsoft.Extensions.ServiceDiscovery.Yarp

为YARP反向代理提供服务发现的扩展。

RESTworld.AspNetCore

包描述

Rocket.Surgery.LaunchPad.Foundation

包描述

Microsoft.Extensions.ServiceDiscovery.Dns

为HttpClient提供扩展,基于DNS记录将知名主机名解析为具体端点。在Kubernetes之类的编排器中用于服务解析。

Jakar.Database

包描述

GitHub仓库 (10)

显示依赖于Microsoft.Extensions.ServiceDiscovery的前5个流行的GitHub仓库

仓库 星级
dotnet/eShop
A reference .NET application implementing an eCommerce site
dotnet/aspire
An opinionated, cloud ready stack for building observable, production ready, distributed applications in .NET
CodeMazeBlog/CodeMazeGuides
The main repository for all the Code Maze guides
dotnet/aspire-samples
dotnet/dotnet
Home of .NET's Virtual Monolithic Repository which includes all the code needed to build the .NET SDK from source
版本 下载 最后更新
8.1.0 44,665 7/23/2024
8.0.2 69,902 6/28/2024
8.0.1 164,231 5/21/2024
8.0.0 84,075 5/21/2024
8.0.0-preview.7.24251.11 41,441 5/7/2024
8.0.0-preview.6.24214.1 48,165 4/23/2024
8.0.0-preview.5.24201.12 42,731 4/9/2024
8.0.0-preview.4.24156.9 56,834 3/12/2024
8.0.0-preview.3.24105.21 70,362 2/13/2024
8.0.0-preview.2.23619.3 75,998 12/20/2023
8.0.0-preview.1.23557.2 65,569 11/14/2023