如何从 API 管理中动态发现托管在 Service Fabric 中的服务?

How can I dynamically discover services hosted in service fabric from API management?

  1. 假设我在服务结构集群中托管了服务 A 和 B。他们分别在端口 7001 和 7002 上监听(在集群内部)。
  2. 假设我将服务架构负载均衡器配置为侦听端口 8001 并将请求转发到服务 A 的端口 7001(在集群内),在端口 8002 上侦听并将请求转发到端口 7002(在集群内)集群)用于服务 B.
  3. 假设我为服务 A 和 B 配置 API 管理并将请求路由到负载平衡器上的适当端口。
  4. 一切正常。
  5. 现在,我不想为每个服务手动映射 url 路由,而是想动态发现服务结构中托管的服务(来自 API 管理)并将请求路由到 运行 动态计时。
  6. 为此,我知道我必须编写一个策略(最有可能在 C# 中)以从某个地方查找此信息。
  7. 但我不确定究竟要查询什么来查找服务结构集群中托管的负载平衡端口和服务。
  8. 我想在同一个服务结构集群中创建另一个服务C并使用它(来自API管理)来提供集群的内部信息。
  9. 但我找不到查找本地服务端口信息或负载均衡服务端口信息的方法。

我该怎么做?

这是一种在集群中发现服务和端点的方法运行。 (请记住,您还需要监控更改。)

private static void ListEndpoints()
{
    var resolver = ServicePartitionResolver.GetDefault();
    var fabricClient = new FabricClient();
    var apps = fabricClient.QueryManager.GetApplicationListAsync().Result;
    foreach (var app in apps)
    {
        Console.WriteLine($"Discovered application:'{app.ApplicationName}");

        var services = fabricClient.QueryManager.GetServiceListAsync(app.ApplicationName).Result;
        foreach (var service in services)
        {
            Console.WriteLine($"Discovered Service:'{service.ServiceName}");

            var partitions = fabricClient.QueryManager.GetPartitionListAsync(service.ServiceName).Result;
            foreach (var partition in partitions)
            {
                Console.WriteLine($"Discovered Service Partition:'{partition.PartitionInformation.Kind} {partition.PartitionInformation.Id}");


                ServicePartitionKey key;
                switch (partition.PartitionInformation.Kind)
                {
                    case ServicePartitionKind.Singleton:
                        key = ServicePartitionKey.Singleton;
                        break;
                    case ServicePartitionKind.Int64Range:
                        var longKey = (Int64RangePartitionInformation)partition.PartitionInformation;
                        key = new ServicePartitionKey(longKey.LowKey);
                        break;
                    case ServicePartitionKind.Named:
                        var namedKey = (NamedPartitionInformation)partition.PartitionInformation;
                        key = new ServicePartitionKey(namedKey.Name);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException("partition.PartitionInformation.Kind");
                }
                var resolved = resolver.ResolveAsync(service.ServiceName, key, CancellationToken.None).Result;
                foreach (var endpoint in resolved.Endpoints)
                {
                    Console.WriteLine($"Discovered Service Endpoint:'{endpoint.Address}");
                }
            }
        }
    }
}

您可以使用 PowerShell 与负载均衡器通信:

Get-AzureRmLoadBalancer

最后,您需要自己想出一种将负载均衡器后端端口与服务端点相匹配的方法。