Service Fabric ServicePartitionResolver.ResolveAsync似乎忽略了负载均衡器

时间:2019-06-14 10:51:42

标签: azure-service-fabric service-fabric-stateless

我有一个无状态服务,充当进入我的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;
    }

我怀疑如果我在群集的所有5个节点上都有一项服务-TestService,则上面的代码将忽略负载均衡器,因此请求将直接转到拾取请求的节点上的实例

有什么办法可以解决这个问题?

那我是否需要实现自己的负载均衡器?来自外部的所有呼叫都进入网关,因为这似乎是推荐的方式,即单入口。但是,由于没有负载均衡器可以选择最佳节点,因此该概念现在似乎会降低速度,并在特定节点上增加更多负载。例如,如果我有一个网关方法GetCars,该方法在所有5个节点上的无状态服务上调用GetCars,那么我想要一种负载平衡方式来对那些节点之一进行负载平衡,而不是所有请求都去本地实例

保罗

1 个答案:

答案 0 :(得分:1)

我希望解析的端点地址包含承载TestService的主副本及其侦听器使用的端口的节点的内部IP地址。

  • 对于有状态服务,这只能是单个端点。

  • 对于Singleton服务,您将从ServicePartitionResolver获得缓存的结果。

您可以使用resolver.ResolveAsync()强制刷新,该更新的重载会占用较早的ResolvedServicePartition

此外,由于内部呼叫不是通过Internet进行的,因此该呼叫将不会通过(Azure)负载均衡器。

添加了更多信息:

可能您将在所有节点上运行网关。如果没有,请确保您这样做。由于每个网关都有自己的解析器,可以解析为“随机”实例,因此您应该会看到负载将自动分散到下游服务中。

P.S。看看Traefik,它可以帮助您解决此问题,而无需构建可靠的反向代理。

更多信息herehere