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
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="8.1.0" />
paket add Microsoft.Extensions.ServiceDiscovery --version 8.1.0
#r "nuget: Microsoft.Extensions.ServiceDiscovery, 8.1.0"
// 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 依赖注入系统注册。
开发人员通常使用IHttpClientFactory
和AddServiceDiscovery
扩展方法将服务发现添加到他们的HttpClient
中,具体操作可参考HttpClient
的相关文档。
可以直接通过调用ServiceEndpointResolver
的GetEndpointsAsync
方法来解析服务,该方法返回一个解析后的端点集合。
变更通知
随着时间推移,服务配置可能会发生变化。服务发现通过支持的基于推送的通知方式来监控端点配置,在不支持时则回退到轮询方式。当端点更新时,调用者会收到通知,以便可以观察新结果。要订阅通知,调用者可以使用ServiceEndpointCollection
的ChangeToken
属性。有关变更令牌的更多信息,请参阅ASP.NET Core中的变更令牌检测更改。
使用功能进行扩展
服务端点(ServiceEndpoint
实例)和服务端点集合(ServiceEndpointCollection
实例)通过它们的Features
属性提供了一个可扩展的IFeatureCollection
。功能作为接口暴露在功能集合上。提供商可以在解析时间添加、修改、包装、替换甚至删除这些接口。可能存在于ServiceEndpoint
中的功能包括:
IHostNameFeature
:暴露解析后的端点的主机名,用于与服务器名标识(SNI)和传输层安全(TLS)一起使用。
解析顺序
在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
的函数。
要配置这些选项,您可以在应用程序的启动类或主程序文件中,使用 IServiceCollection
的 Configure
扩展方法。
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
上配置 AllowedSchemes
和 AllowAllSchemes
属性来过滤方案。 AllowAllSchemes
属性用来指示允许所有方案。默认情况下,AllowAllSchemes
为 true
,并允许所有方案。可以通过将 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应用将引用的项目(catalog和basket)的服务发现信息传递到前端项目。
命名端点
一些服务公开了多个命名端点。可以通过在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的命名端点。
反馈 & 贡献
产品 | 版本 兼容的和额外的计算的目标框架版本。 |
---|---|
.NET | net8.0是兼容的。 net8.0-android已被计算。 net8.0-browser已被计算。 net8.0-ios已被计算。 net8.0-maccatalyst已被计算。 net8.0-macos已被计算。 net8.0-tvos已被计算。 net8.0-windows已被计算。 |
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.ServiceDiscovery.Abstractions (>= 8.1.0)
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 |