从分区 ID 确定分区键(名称或编号范围)
Determine partition key (name or number range) from partition ID
对于有状态服务,副本是否可以通过其分区 ID(GUID 值)确定分区键(字符串或 number/number 范围)?查看 .NET API,只能从 ServicePartitionKey
获取副本 ID,反之则不行。
不,您无法直接从分区 ID (guid) 获取它。根据您使用的分区类型(Singleton、Int64Range 或 Named)以及设置方式,可能 派生它 ,但无法直接从服务进行。
这样做是有道理的,请考虑这样一种情况,您的服务具有 low key = 0
和 high key = 9
以及 2 个分区的 Int64 分区方案。从 0 到 4 的任何分区键都将在分区号上结束。分区号上的 1 和键 5 - 9 2. 但是由于任何使用 0 到 4 键的调用都会在该服务的 相同实例 上结束,因此键实际上是 per call,而不是 per service,所以从服务的角度来看,它如何知道它的分区对应于哪个键,除非那是客户端调用服务的东西,你可以说 "for this call to partition XXX the key is 123"。目前没有这样的信息融入到结构传输通信中,分区在客户端解析,从未传递给服务。
您可以做的是找出分区 ID 所在的范围。对于单例分区方案,您在 'the partition' 上,这里没有更多讨论。对于 Named 和 Int64,您可以使用 FabricClient.QueryManager
枚举分区:
var fabricClient = new FabricClient();
var partitionList = await fabricClient.QueryManager.GetPartitionListAsync(serviceName);
foreach (var partition in partitionList)
{
// Partition Guid
var partitionId = partition.PartitionInformation.Id;
// Int 64 Range
var int64PartitionInfo = partition.PartitionInformation as Int64RangePartitionInformation;
var lowKey = int64PartitionInfo?.LowKey;
var highKey = int64PartitionInfo?.HighKey;
// Named Range
var namedPartitionInfo = partition.PartitionInformation as NamedPartitionInformation;
var name = namedPartitionInfo.Name;
}
对于命名范围 if 实际上确实为您提供了分区键,因为它是那里的 one-to-one 映射,但对于 Int64 范围,您将只能获得该分区的整数范围。
上面的代码也是您可能不希望每次要查找分区键时 运行 因为 FabricClient.QueryManager
相对较慢。
如果知道每次服务调用中的分区键对您来说很重要,那么您还有另一个选择,就是将其作为消息参数或消息头添加到您对客户端的调用中(类似对此 )
yoape 回答的真好,应该从客户端需要从服务外部知道分区信息的场景考虑。但它表明从服务本身内部是不可能的。
根据问题,它要求从服务本身内部获取此信息,并且可以获取如下分区信息。
假设您有这样的 StatefulService:
class WorkerService : StatefulService {}
在该服务中,您可以获得这样的分区信息:
switch (this.Partition.PartitionInfo.Kind)
{
case ServicePartitionKind.Int64Range:
var rangePartition = this.Partition.PartitionInfo as Int64RangePartitionInformation;
var lowKey = rangePartition.LowKey;
var highKey = rangePartition.HighKey;
break;
case ServicePartitionKind.Named:
var namedPartition = this.Partition.PartitionInfo as NamedPartitionInformation;
var name = namedPartition.Name;
break;
case ServicePartitionKind.Singleton:
var singleton = this.Partition.PartitionInfo as SingletonPartitionInformation;
var PartitionId = singleton.Id;
break;
default:
var PartitionId2 = this.Partition.PartitionInfo.Id;
break;
}
单例与默认相同,都使用分区的 id。
对于有状态服务,副本是否可以通过其分区 ID(GUID 值)确定分区键(字符串或 number/number 范围)?查看 .NET API,只能从 ServicePartitionKey
获取副本 ID,反之则不行。
不,您无法直接从分区 ID (guid) 获取它。根据您使用的分区类型(Singleton、Int64Range 或 Named)以及设置方式,可能 派生它 ,但无法直接从服务进行。
这样做是有道理的,请考虑这样一种情况,您的服务具有 low key = 0
和 high key = 9
以及 2 个分区的 Int64 分区方案。从 0 到 4 的任何分区键都将在分区号上结束。分区号上的 1 和键 5 - 9 2. 但是由于任何使用 0 到 4 键的调用都会在该服务的 相同实例 上结束,因此键实际上是 per call,而不是 per service,所以从服务的角度来看,它如何知道它的分区对应于哪个键,除非那是客户端调用服务的东西,你可以说 "for this call to partition XXX the key is 123"。目前没有这样的信息融入到结构传输通信中,分区在客户端解析,从未传递给服务。
您可以做的是找出分区 ID 所在的范围。对于单例分区方案,您在 'the partition' 上,这里没有更多讨论。对于 Named 和 Int64,您可以使用 FabricClient.QueryManager
枚举分区:
var fabricClient = new FabricClient();
var partitionList = await fabricClient.QueryManager.GetPartitionListAsync(serviceName);
foreach (var partition in partitionList)
{
// Partition Guid
var partitionId = partition.PartitionInformation.Id;
// Int 64 Range
var int64PartitionInfo = partition.PartitionInformation as Int64RangePartitionInformation;
var lowKey = int64PartitionInfo?.LowKey;
var highKey = int64PartitionInfo?.HighKey;
// Named Range
var namedPartitionInfo = partition.PartitionInformation as NamedPartitionInformation;
var name = namedPartitionInfo.Name;
}
对于命名范围 if 实际上确实为您提供了分区键,因为它是那里的 one-to-one 映射,但对于 Int64 范围,您将只能获得该分区的整数范围。
上面的代码也是您可能不希望每次要查找分区键时 运行 因为 FabricClient.QueryManager
相对较慢。
如果知道每次服务调用中的分区键对您来说很重要,那么您还有另一个选择,就是将其作为消息参数或消息头添加到您对客户端的调用中(类似对此
yoape 回答的真好,应该从客户端需要从服务外部知道分区信息的场景考虑。但它表明从服务本身内部是不可能的。
根据问题,它要求从服务本身内部获取此信息,并且可以获取如下分区信息。
假设您有这样的 StatefulService:
class WorkerService : StatefulService {}
在该服务中,您可以获得这样的分区信息:
switch (this.Partition.PartitionInfo.Kind)
{
case ServicePartitionKind.Int64Range:
var rangePartition = this.Partition.PartitionInfo as Int64RangePartitionInformation;
var lowKey = rangePartition.LowKey;
var highKey = rangePartition.HighKey;
break;
case ServicePartitionKind.Named:
var namedPartition = this.Partition.PartitionInfo as NamedPartitionInformation;
var name = namedPartition.Name;
break;
case ServicePartitionKind.Singleton:
var singleton = this.Partition.PartitionInfo as SingletonPartitionInformation;
var PartitionId = singleton.Id;
break;
default:
var PartitionId2 = this.Partition.PartitionInfo.Id;
break;
}
单例与默认相同,都使用分区的 id。