Service Fabric ServicePartitionResolver.ResolveAsync 似乎忽略了负载均衡器
Service Fabric ServicePartitionResolver.ResolveAsync appears to ignore load balancer
我有一个无状态服务,它充当所有请求进入我的 5 节点集群的网关
此服务将请求转发到集群内的服务
protected virtual async Task<ResolvedServicePartition> FindPartitionAsync(long key = 0)
{
var resolver = ServicePartitionResolver.GetDefault();
var result = await resolver.ResolveAsync(FullServiceName, ServicePartitionKey.Singleton, CancellationToken.None).ConfigureAwait(false);
return result;
}
private async Task<string> EstablishProxyUrlAsync(string method, long key = 0)
{
var partition = await FindPartitionAsync(key).ConfigureAwait(false);
if (key != 0)
{
Log.Information($"{this.GetType().Name} method {method} request resolved by partition {partition.Info.Id}");
}
var endpoints = JObject.Parse(partition.GetEndpoint().Address)["Endpoints"];
var address = endpoints[""].ToString().TrimEnd('/');
var proxyUrl = $"{address}/api/{Area}/{method}";
return proxyUrl;
}
我怀疑如果我有一个服务 - TestService 在我的集群的所有 5 个节点上,上面的代码会忽略负载平衡器,因此请求只会转到接收请求的节点上的实例
有什么办法可以解决这个问题吗?
那我需要实现自己的负载均衡器吗?来自外部的所有调用都进入网关,因为这似乎是推荐的方式,即单一入口点。然而,似乎这个概念现在会减慢速度并在特定节点上施加更多负载,因为没有负载均衡器来选择最佳节点。例如,如果我有一个网关方法 GetCars,它在跨所有 5 个节点的无状态服务上调用 GetCars,我想要一种对这些节点之一进行负载平衡的方法,而不是所有请求都转到本地实例
保罗
我希望解析的端点地址包含托管 TestService 的主要副本的节点的内部 IP 地址及其侦听器使用的端口。
对于有状态服务,这只能是一个单个端点。
对于单例服务,您将从 ServicePartitionResolver
获得缓存结果。
您可以使用 resolver.ResolveAsync()
强制刷新,它的重载采用较早的 ResolvedServicePartition
。
此外,由于内部调用不是通过 Internet 进行的,因此调用不会通过 (Azure) 负载平衡器。
添加了更多信息:
您可能 运行 所有节点上的网关。如果没有,请确保您这样做。由于每个网关都有自己的解析器来解析 'random' 实例,您应该会看到负载将自动分布到下游服务。
P.S。看看 Traefik,它可以帮助您解决这个问题,而无需构建可靠的反向代理。
我有一个无状态服务,它充当所有请求进入我的 5 节点集群的网关
此服务将请求转发到集群内的服务
protected virtual async Task<ResolvedServicePartition> FindPartitionAsync(long key = 0)
{
var resolver = ServicePartitionResolver.GetDefault();
var result = await resolver.ResolveAsync(FullServiceName, ServicePartitionKey.Singleton, CancellationToken.None).ConfigureAwait(false);
return result;
}
private async Task<string> EstablishProxyUrlAsync(string method, long key = 0)
{
var partition = await FindPartitionAsync(key).ConfigureAwait(false);
if (key != 0)
{
Log.Information($"{this.GetType().Name} method {method} request resolved by partition {partition.Info.Id}");
}
var endpoints = JObject.Parse(partition.GetEndpoint().Address)["Endpoints"];
var address = endpoints[""].ToString().TrimEnd('/');
var proxyUrl = $"{address}/api/{Area}/{method}";
return proxyUrl;
}
我怀疑如果我有一个服务 - TestService 在我的集群的所有 5 个节点上,上面的代码会忽略负载平衡器,因此请求只会转到接收请求的节点上的实例
有什么办法可以解决这个问题吗?
那我需要实现自己的负载均衡器吗?来自外部的所有调用都进入网关,因为这似乎是推荐的方式,即单一入口点。然而,似乎这个概念现在会减慢速度并在特定节点上施加更多负载,因为没有负载均衡器来选择最佳节点。例如,如果我有一个网关方法 GetCars,它在跨所有 5 个节点的无状态服务上调用 GetCars,我想要一种对这些节点之一进行负载平衡的方法,而不是所有请求都转到本地实例
保罗
我希望解析的端点地址包含托管 TestService 的主要副本的节点的内部 IP 地址及其侦听器使用的端口。
对于有状态服务,这只能是一个单个端点。
对于单例服务,您将从
ServicePartitionResolver
获得缓存结果。
您可以使用 resolver.ResolveAsync()
强制刷新,它的重载采用较早的 ResolvedServicePartition
。
此外,由于内部调用不是通过 Internet 进行的,因此调用不会通过 (Azure) 负载平衡器。
添加了更多信息:
您可能 运行 所有节点上的网关。如果没有,请确保您这样做。由于每个网关都有自己的解析器来解析 'random' 实例,您应该会看到负载将自动分布到下游服务。
P.S。看看 Traefik,它可以帮助您解决这个问题,而无需构建可靠的反向代理。