【问题标题】:Get All Active Service Instances on Service Start在服务启动时获取所有活动服务实例
【发布时间】:2016-06-26 07:24:02
【问题描述】:

我正在 Azure Service Fabric 中创建无状态服务。但是,一旦服务启动(或自定义通信侦听器启动),我需要获取该服务的所有其他实例/分区的地址。

我这样做是通过创建新的FabricClient 并调用fabricClient.QueryManager.GetPartitionListAsync(serviceUri) 来实现的。但是,当第一个服务实例开始运行时,我收到了 FabricServiceNotFoundException 消息服务不存在。

我在文档中找不到,所以我的问题是:当该服务的新实例启动时,如何获取在 Azure Service Fabric 中运行的特定服务的所有活动实例的侦听端点地址列表跑步吗?

【问题讨论】:

    标签: azure-service-fabric service-discovery


    【解决方案1】:

    端点地址实际上位于服务副本和实例上 - 这些是实际放置在节点上的东西。在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" }
          ...
    }
    

    请记住,副本/实例何时出现并不能保证顺序,因此您可能需要重试几次。此外,副本和实例有时会在服务的整个生命周期中移动,因此您需要使列表保持最新。基本上,您不能真正一次性获得所有这些信息并做好准备,因为它是一个非常动态的系统。

    请参阅此处了解概览: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-connect-and-communicate-with-services/

    更多详细信息请点击此处:https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-communication/

    【讨论】:

    • 抱歉,您的解决方案也以System.Fabric.FabricServiceNotFoundException: 服务不存在 消息告终。我想这是服务结构的工作方式。
    • 您在服务生命周期的哪个阶段尝试获取每个实例或副本的地址?
    • 在互联网的其他任何地方都找不到此信息...谢谢
    • 序列化奇怪的 Endpoints json 语法的最佳方法是什么?我尝试过的所有 linter 和解析器都无法验证该 json。如果端点是一个列表,它确实应该有方括号。
    【解决方案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);代替!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      相关资源
      最近更新 更多