.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(S) 终结点时的方案选择

在本地开发和测试服务时通常使用 HTTP,而在部署服务时通常使用 HTTPS。 服务发现通过允许在提供给服务发现的输入字符串中指定 URI 方案的优先级列表来支持这一点。 服务发现将尝试按顺序解析方案的服务,并在找到终结点后停止。 URI 方案由 + 字符分隔,例如:"https+http://basket"。 服务发现将首先尝试查找 "basket" 服务的 HTTPS 终结点,然后回退到 HTTP 终结点。 如果找到任何 HTTPS 终结点,服务发现将不包括 HTTP 终结点。

可以通过在 ServiceDiscoveryOptions 上配置 AllowedSchemesAllowAllSchemes 属性来筛选方案。 AllowAllSchemes 属性用于指示允许所有方案。 默认情况下,AllowAllSchemestrue,并允许所有方案。 可以通过将 AllowAllSchemes 设置为 false 并将允许的方案添加到 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"。 每次解析目录时,都会选择其中一个终结点。

如果使用 IServiceCollection 上的 AddServiceDiscoveryCore 扩展方法将服务发现添加到主机,则可以通过在 IServiceCollection 上调用 AddConfigurationServiceEndpointProvider 扩展方法来添加基于配置的终结点解析程序。

配置

配置解析程序是使用 ConfigurationServiceEndpointProviderOptions 类配置的,该类提供以下配置选项:

  • SectionName:包含服务终结点的配置节的名称。 默认为 "Services"

  • ApplyHostNameMetadata:用于确定是否应将主机名元数据应用于已解析终结点的委托。 它默认为返回 false 的函数。

若要配置这些选项,可以对应用程序的 Startup 类或 Program 文件中的 IServiceCollection 使用 Configure 扩展方法:

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 容器应用和 Kubernetes(如果已相应地配置))提供服务发现功能,而无需服务发现客户端库。 如果在此类环境中部署了应用程序,使用平台的内置功能可能很有利。 直通解析程序旨在帮助实现此方案。 它可以在不同的环境(如开发人员的计算机)中启用替代解析程序(如配置)。 重要的是,无需进行任何代码修改或实现条件防护,即可实现这种灵活性。

直通解析程序不执行外部解析,而是通过返回以 DnsEndPoint 表示的输入服务名称来解析终结点。

通过 AddServiceDiscovery 扩展方法添加服务发现时,默认会配置直通提供程序。

如果使用 IServiceCollection 上的 AddServiceDiscoveryCore 扩展方法将服务发现添加到主机,则可以通过调用 IServiceCollection 上的 AddPassThroughServiceEndpointProvider 扩展方法来添加直通提供程序。

另请参阅