如何从API管理中动态发现服务结构中托管的服务?

时间:2016-07-22 04:32:13

标签: azure-service-fabric

  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. 但我无法找到查找本地服务端口信息或加载平衡服务端口信息的方法。
  10. 我该如何解决?

1 个答案:

答案 0 :(得分:21)

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

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

最后,您需要找到一种方法将负载均衡器后端端口与服务端点匹配。