从 Consul DNS 服务器获取服务端口

Getting Service Port from Consul DNS Server

我正在使用 Consul 进行服务发现。 Consul 服务器 运行ning 在 192.168.61.10 上。我有多种服务如下:- 服务 A - 一个实例,服务 B - 两个实例,在 192.168.61.125 的 2222 端口和另一个在 192.168.61.126 的 3333 端口。

这两个服务都在 .NET Core 3.1 中,我正在使用 nuget 包 Consul 1.6.10.1 进行服务注册、健康检查和服务注销。我不想在任何服务的配置文件中添加目标服务的地址。

在典型的业务用例中,服务 A 正在调用服务 B。我能够将我的服务 B 解析为 serviceb.service.consul 并使用 Consul DNS 服务器获取这两个 IP 地址。 现在调用服务 B 我只想要它正在侦听的端口。 我发现有一个 nuget 包 DnsClient 可以在代码中给出完整的 SRV 记录,我可以获得所有目标服务实例的完整地址。

void QueryService()
{
    LookupClient lookUpClient = new LookupClient(IPAddress.Parse("192.168.61.10"), 8600);
    IDnsQueryResponse result = lookUpClient.Query("serviceb.service.consul", QueryType.SRV);
    var port = ((SrvRecord)result.Answers.First()).Port;
    using (var httpClient = new HttpClient())
    {
      var response = httpClient.GetStringAsync($"http://serviceb.service.consul:{port}/weatherforecast");
      Console.WriteLine(response.Result);
     }
}

现在我的问题是,如果我需要使用代码解决此问题,那么所有负载平衡责任都由代码本身承担,我认为这是不正确的。一种解决方案是我可以使用默认的 http/https 端口(80 或 443)来解决我的问题。但这将限制我每个 VM 运行 一项服务。那么有什么解决办法吗

当应用程序向 Consul 的 DNS 服务器发送查询时,服务器会在每个查询的响应中随机化服务实例集。如果注册实例的总数超过可以在 UDP 数据包中发送的数量,则响应将仅包含可用服务实例 IP 的 子集 。如果 enable_truncate 设置为 true,将在响应中设置截断标志以指示如果使用 TCP 重试查询,可以提供更多信息。

例如,如果您在 Consul 中注册了 25 个服务 B 实例,并且您的应用程序使用 UDP 查询 Consul 的 DNS 服务器,您可能只会在给定的响应数据中收到有关这些服务实例中 3-4 个的信息询问。由于顺序是随机的,因此后续的 DNS 请求可能 return 一组不同的 IP。这种随机化提供了跨上游服务的非常简单的请求负载平衡。

您可以修改您的应用程序,使其连接到 DNS 响应中随机 IP 列表中的随机实例,但如果您只想随机化连接,那么这对于 Consul 已经提供的内容来说可能是多余的可用的上游主机。