.NET 中的服务发现

本文介绍如何使用 Microsoft.Extensions.ServiceDiscovery 库。服务发现是开发人员使用逻辑名称而不是物理地址(IP 地址和端口)来引用外部服务的一种方法。

开始使用

若要在 .NET 中开始使用服务发现,请安装 Microsoft.Extensions.ServiceDiscovery NuGet 包。

dotnet add package Microsoft.Extensions.ServiceDiscovery --prerelease

用法示例

在项目的 Program.cs 文件中调用 AddServiceDiscovery 扩展方法,以将服务发现添加到主机,并配置默认服务终结点解析程序:

builder.Services.AddServiceDiscovery();

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

builder.Services.AddHttpClient<CatalogServiceClient>(static client =>

    {

        client.BaseAddress = new("http://catalog");

    })

    .UseServiceDiscovery();

或者,在默认情况下,可以将服务发现添加到所有 HttpClient 实例:

builder.Services.ConfigureHttpClientDefaults(static http =>

{

    // Turn on service discovery by default

    http.UseServiceDiscovery();

});

从配置解析服务终结点

默认情况下,AddServiceDiscovery 扩展方法会添加基于配置的终结点解析程序。此解析程序从 .NET 配置系统读取终结点。库通过 appsettings.json、环境变量或任何其他 IConfiguration 源支持配置。

以下示例演示如何通过 appsettings.json 为名为 catalog 的服务配置终结点:

{

  "Services": {

      "catalog": [

        "localhost:8080",

        "10.46.24.90:80",

      ]

    }

}

上面的示例为名为 catalog 的服务添加两个终结点:localhost:8080 和 "10.46.24.90:80"。每次解析 catalog 时,都会选择其中一个终结点。

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

配置

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

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

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

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

9b2222d7c42b361ad454e2e28b313244.png

上面的示例演示如何为服务终结点设置自定义节名称,并提供一个基于条件应用主机名元数据的自定义逻辑。

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

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

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

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

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

使用终结点选择器进行负载均衡

每次通过 HttpClient 管道解析终结点时,都会从所请求服务的所有已知终结点集选择一个终结点。如果有多个终结点可用,则可能需要在所有此类终结点之间平衡流量。为此,可以使用可自定义的终结点选择器。默认情况下,终结点是按轮循顺序选择的。若要使用不同的终结点选择器,请向 UseServiceDiscovery 方法调用提供 IServiceEndPointSelector 实例。例如,若要从解析的终结点集选择一个随机终结点,请将 RandomServiceEndPointSelector.Instance 指定为终结点选择器: 

d90859727c01361879f91155e03db2ce.png

Microsoft.Extensions.ServiceDiscovery 包包含以下终结点选择器提供程序:

  • Pick-first:始终选择第一个终结点:PickFirstServiceEndPointSelectorProvider.Instance

  • Round-robin:循环选择终结点:RoundRobinServiceEndPointSelectorProvider.Instance

  • Random:随机选择终结点:RandomServiceEndPointSelectorProvider.Instance

  • Power-of-two-choices:尝试根据用于分布式负载均衡的二次幂选择算法选取负载最低的终结点,在提供的任一终结点都没有 IEndPointLoadFeature 特征时,会降级为随机选择终结点:PowerOfTwoChoicesServiceEndPointSelectorProvider.Instance

终结点选择器是通过 IServiceEndPointSelectorProvider 实例创建的,例如之前列出的提供程序。调用提供程序的 CreateSelector() 方法来创建选择器,这是 IServiceEndPointSelector 的实例。使用 SetEndPoints(ServiceEndPointCollection collection) 方法解析 IServiceEndPointSelector 实例时,将为其提供已知终结点集。若要从集合中选择终结点,需调用 GetEndPoint(object? context) 方法,这会返回单个 ServiceEndPoint。传递给 GetEndPoint 的 context 值用于提供可能对选择器有用的额外上下文。例如,在 HttpClient 案例中,传递了 HttpRequestMessage。提供的 IServiceEndPointSelector 实现都不会检查上下文,除非使用选择器(这样就不会该实现),否则可以忽略它。

解析顺序

在解析服务终结点时,将按注册顺序调用每个已注册的解析程序,并且你有机会修改返回给调用方的 ServiceEndPoint 集合。如果在调用 Microsoft.Extensions.ServiceDiscovery 系列包中包含的提供程序时集合中存在现有的终结点,则这些提供程序会跳过解析。例如,假设注册了以下提供程序:配置DNS SRV直通。解析发生时,将按顺序调用这些提供程序。如果配置提供程序未发现任何终结点,则 DNS SRV 提供程序执行解析,并可能会添加一个或多个终结点。如果 DNS SRV 提供程序向集合添加终结点,则直通提供程序将跳过其解析并立即返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值