Search code examples
c#.netazuremicroservicesazure-service-fabric

How to get instance count of Service Fabric microservices?


I have service. It makes request to 3rd-party API. As that API has set amount of requests per second, I need to set limits to my requests.

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

I have this configuration. "-1" means max available amount if I'm not wrong.

How can I get amount of instances of "MyService" ? Should I also count amount of partitions to get real amount of instanses?


Solution

  • In simple terms, is just getting the number of Partitions multiplied by the number of allocated replicas(stateful) or instances(stateless) a service has:

    In your case, you set the instance count to -1, assuming the number of nodes is 3, the math would be:

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

    Using 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
    

    Using 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();
    }
    

    The scripts above should works for Stateful and Stateless.

    There are some caveats:

    • Stateful services has the concept of primary and secondary, if you do not process requests in the secondary, you should consider only the number partitions(that will be the same as the number of primary replicas)
    • Don't assume the node count as the number of instances when -1 is set, SF will place the services in the node only if the node is available for that replica, that means:
      • if the node is not disabled, a replica\instance won't be allocated on disabled nodes
      • if the node has no capacity for the replica
      • if the service has placement constraints
      • if the service is block listed in the node
    • Based on the rules above, do not consider the InstanceCount either, because SF might not be able to place the number of replicas requested. And when the InstanceCount is -1, you have to iterate all the replicas\instances.
    • As noted above, consider only replicas in Ready Status. I am not taking into account instances being in other status like 'InBuild' 'Deleting' and so on.