如何获取 Service Fabric 微服务的实例数?

How to get instance count of Service Fabric microservices?

我有服务。它向第 3 方 API 发出请求。由于 API 设置了每秒的请求数量,我需要为我的请求设置限制。

<DefaultServices>
    <Service Name="MyService">
      <StatelessService ServiceTypeName="MyService" InstanceCount="-1">
        <UniformInt64Partition PartitionCount="5" LowKey="0" HighKey="5" />
      </StatelessService>
    </Service>
  </DefaultServices>

我有这个配置。如果我没记错的话,“-1”表示最大可用量。

如何获取 "MyService" 的实例数量?我还应该计算分区数量以获得实际数量的实例吗?

InstanceCount 为 -1 表示该服务的实例在集群中的每个节点上 运行。因此,一个 5 节点集群将有 5 个 MyService 运行 实例,每个节点一个。无状态服务没有分区(嗯,只有一个,SingletonPartition

因此,要获取实例数,您只需查看 InstanceCount 的值即可。如果是<> -1那么就是节点数,否则就是实例数。

如果您希望以编程方式执行此操作,请尝试 FabricClient class:

var fabricClient = new FabricClient();
var partitions = await fabricClient.QueryManager.GetPartitionListAsync(new Uri("fabric:/Application2/Stateless1"));
var singletonPartition = (StatelessServicePartition)partitions.First(); // stateless service has just one partition
Console.WriteLine(singletonPartition.InstanceCount);

简单来说,就是将分区数乘以服务具有的已分配副本(有状态)或实例(无状态)数:

在您的情况下,您将实例计数设置为 -1,假设节点数为 3,则数学计算为:

3(instances) * 5(partitions) = 15 (instances)

使用 PowerShell

$instances =  0
foreach ($partition in Get-ServiceFabricPartition -ServiceName "fabric:/AppName/ServiceName") {
   foreach ($replica in Get-ServiceFabricReplica -PartitionId $partition.PartitionId) 
   {
        if($replica.ReplicaStatus -eq 'Ready'){
            $instances++ 
        }
   }
}
echo $instances

使用 FabricClient:

int instances = 0;
var fabricClient = new FabricClient();
var partitions = await fabricClient.QueryManager.GetPartitionListAsync(new Uri("fabric:/AppName/ServiceName"));
foreach (var partition in partitions)
{
    instances += (await fabricClient.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id)).Where(r => r.ReplicaStatus == ServiceReplicaStatus.Ready).Count();
}

上面的脚本应该适用于有状态和无状态。

有一些注意事项:

  • Stateful services有primary和secondary的概念,如果你不在secondary处理请求,你应该只考虑partitions的数量(与primary的副本数量相同)
  • 设置-1时不要假设节点计数为实例数,只有当该节点可用于该副本时,SF才会将服务放置在该节点中,这意味着:
    • 如果节点没有被禁用,一个replica\instance不会被分配到被禁用的节点上
    • 如果节点没有副本容量
    • 如果服务有放置限制
    • 如果服务在节点中被阻止列出
  • 根据上面的规则,也不要考虑InstanceCount,因为SF可能无法放置请求的副本数。而当InstanceCount为-1​​时,你必须遍历所有的replicas\instances.
  • 如上所述,仅考虑处于就绪状态的副本。我没有考虑处于其他状态的实例,例如 'InBuild' 'Deleting' 等等。