我正在Azure Service Fabric中创建无状态服务。但是,一旦服务启动(或启动自定义通信侦听器),我需要获取该服务的所有其他实例/分区的地址。
我是通过创建新的FabricClient
并调用fabricClient.QueryManager.GetPartitionListAsync(serviceUri)
来实现的。但是,当第一个服务实例开始运行时,我收到FabricServiceNotFoundException
消息服务不存在。。
我在文档中找不到,所以我的问题是:当该服务的新实例启动时,如何获取Azure Service Fabric中运行的特定服务的所有活动实例的侦听端点地址列表运行
答案 0 :(得分:4)
端点地址实际上位于服务副本和实例上 - 这些是实际放置在节点上的内容。在名为ServiceManagerClient的ResolveServicePartitionAsync中有一种特殊的方法。
在Reliable Services SDK(在Microsoft.ServiceFabric.Services.Client命名空间中),我们提供了一个解析器实用程序,使其更容易:
ServicePartitionResolver resolver = ServicePartitionResolver.GetDefault();
ResolvedServicePartition partition =
await resolver.ResolveAsync(new Uri("fabric:/MyApp/MyService"), new ServicePartitionKey(), cancellationToken);
ResolvedServicePartition的Endpoints属性是分区中每个副本/实例的列表。 Address属性将包含一个JSON对象,它是一个键值对列表,包含由副本/实例打开的每个侦听器:
{
"Endpoints" :
{ "mylistener1" : "some-address" },
{ "mylistener2" : "some-address" }
...
}
请注意,当副本/实例出现时,没有保证的顺序,因此您可能需要重试几次。此外,副本和实例有时会在服务的整个生命周期内移动,因此您需要使列表保持最新。基本上你不能一次性预先获取所有这些信息并设置,因为它是一个非常动态的系统。
答案 1 :(得分:2)
我是对StackOverflow发表评论的新人,但这是我如何进行服务解析。我最终建立了一个小型图书馆来处理它。
ResolvedServicePartition partition = await fabricClient.ServiceManager.ResolveServicePartitionAsync("fabric:/Application1/Service1");
// This "endpoint" looks something like this: {\"Endpoints\":{\"\":\"http:\/\/localhost:8448\/\"}}
string randomConfigStoreEndpointJson = partition.GetEndpoint().Address;
// Use Newtonsoft.Json to parse this mess, since JavaScriptSerializer isn't up to the job
JObject endpointObject = JObject.Parse(randomConfigStoreEndpointJson);
// This is the only way I could actually extract the baseUrl without regular expressions
string actualEndpointBaseUrl = endpointObject["Endpoints"].First.First.ToString();
@DannyMeister这用于解析奇数端点JSON语法。
这也可以解决只有一个分区的有状态服务。要解析具有多个分区的有状态服务,您必须在客户端上找出partitionKey,然后再调用await fabricClient.ServiceManager.ResolveServicePartitionAsync("fabric:/Application1/Service1", statefulPartitionKey);
!