【问题标题】:How to update HttpClient base address at runtime in ASP.net core如何在 ASP.net 核心运行时更新 HttpClient 基地址
【发布时间】:2021-08-08 09:55:08
【问题描述】:

我使用 ASP.net 核心 API 创建了几个微服务
这些微服务之一返回其他微服务的确切地址
如果地址更改,如何在不重新启动的情况下更新这些微服务的地址

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient("MainMicroservice", x =>
        {
            x.BaseAddress = new Uri("http://mainmicroservice.com");
        });
        services.AddHttpClient("Microservice1", x =>
        {
            x.BaseAddress = new Uri("http://microservice1.com");
        });
        services.AddHttpClient("Microservice2", x =>
        {
            x.BaseAddress = new Uri("http://microservice2.com");
        });
        services.AddHttpClient("Microservice3", x =>
        {
            x.BaseAddress = new Uri("http://microservice3.com");
        });
    }
}
public class Test
{
    private readonly IHttpClientFactory _client;

    public Test(IHttpClientFactory client)
    {
        _client = client;
    }

    public async Task<string> Test()
    {
        var repeat = false;

        do
        {
            try
            {
                return await _client
                    .CreateClient("Microservice1")
                    .GetStringAsync("Test")
                    .ConfigureAwait(false);
            }
            catch (HttpRequestException e) when (e.StatusCode == HttpStatusCode.NotFound)
            {
                var newAddress = await _client
                    .CreateClient("MainMicroservice")
                    .GetStringAsync("Microservice1")
                    .ConfigureAwait(false);

                //todo change address of microservice1

                repeat = true;
            }
        } while (repeat);
    }
}

【问题讨论】:

  • 不分配基地址,给出调用GET、POST、PUT时的地址
  • 性能方面有问题吗?
  • 听起来第一个服务真的是一个配置源。您可以将其添加为 custom configuration provider 并使用它在您的 HttpClient 注册中提供的 URL。
  • OTOH 你问的是 DNS 的作用。如果您可以控制您的 DNS 域,则可以使用 ALIAS 记录创建重定向到特定服务器的知名服务名称。这样,将流量定向到不同服务器所需的只是更改 ALIAS
  • @Mehdi 不,不包括性能问题,但请确保您只有 1 个 httpclient 实例。如果您创建多个实例,则会导致性能影响

标签: c# asp.net-core microservices httpclient


【解决方案1】:

如果您迟早(相当早)构建基于微服务的解决方案,您将遇到一个服务需要与另一个服务通信的情况。为了做到这一点,调用者必须知道目标微服务在网络中的确切位置,它们在其中运行。

您必须以某种方式提供目标微服务侦听请求的IP 地址端口。您可以使用配置文件或环境变量来做到这一点,但这种方法有一些缺点和限制。

  1. 首先是您必须维护并正确部署 所有环境的配置文件:本地开发, 测试、预生产和生产。忘记更新任何 添加新服务或移动现有服务时的这些配置 一个到不同的节点会导致在运行时发现错误。
  2. 其次,更重要的问题是它只能在静态 环境,这意味着您不能动态添加/删除节点, 因此您将无法动态扩展您的系统。这 自主扩展和部署给定微服务的能力是其中之一 基于微服务架构的关键优势,我们做到了 不想失去这种能力。

因此我们需要引入服务发现。服务发现是一种允许服务找到彼此的网络位置的机制。这种模式有很多可能的实现方式。

我们有两种类型的服务发现:客户端和服务器端,您可以在 ASP.NET 项目中找到一个很好的 NuGet 包来处理。

【讨论】:

  • 但是,如果你想实现你在问题中提到的场景,我认为你不应该对地址进行硬编码,而是可以从缓存中读取数据(如 Redis 等)。然后每当地址发生变化时,您只需要将缓存值无效并在缓存中设置一个新值。
  • 或者使用Kubernetes和DNS,直接通过名字访问服务。
  • @Riwen Kubernetes 不需要使用 DNS。您描述的是 DNS ALIAS 记录的工作
  • @PanagiotisKanavos 不是说需要。不过,这让整个事情变得如此简单。
  • 我认为他的意思是我们可以为我们的容器指定一个名称,并且每个 docker 容器都可以使用该名称相互调用。 Kubernetes 和 Swarm docker 可以让它变得更容易。
猜你喜欢
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
  • 2017-10-12
  • 2019-10-24
  • 2020-03-16
  • 2019-09-16
  • 2021-03-24
相关资源
最近更新 更多