对于有状态服务,副本是否可以通过其分区ID(GUID值)确定分区键(字符串或数字/数字范围)?查看.NET API,只能从ServicePartitionKey
获取副本ID,而不是相反。
答案 0 :(得分:5)
不,你无法直接从分区ID(guid)获取它。根据您使用的分区类型(Singleton,Int64Range或Named)以及如何设置,可能派生,但无法直接从服务中执行此操作。
这是有道理的,考虑这样一种情况,即您拥有一个带有low key = 0
和high key = 9
和2个分区的Int64分区方案的服务。从0到4的任何分区键最终都会在分区号上结束。分区号为1和键5-9。 2.但是,由于任何使用0到4键的调用最终都会在该服务的同一实例上结束,因此该键实际上是每次调用,而不是每个服务,所以从服务的角度来看,它如何知道它的分区对应哪个密钥,除非这是客户端对服务的调用中的内容,你可以说“对于这个分区XXX的调用关键是123“。目前没有这样的信息烘焙到结构传输通信中,分区在客户端解析,从未传递给服务。
你可以做的是找出分区ID所在的范围。对于Singleton分区方案,你在“分区”上,在那里讨论的不多。对于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;
}
对于命名范围,如果实际上确实为您提供了分区键,因为它是一对一映射,但对于Int64范围,您将只获得该分区的整数范围。
上面的代码也是您每次想要查找分区键时可能不想运行的代码,因为FabricClient.QueryManager
相对较慢。
您拥有的另一个选项,如果您能够知道每个服务调用中的分区键很重要,只需将其作为消息参数或消息头添加到您对客户端的调用中(类似于此Passing user and auditing information in calls to Reliable Services in Service Fabric transport)
答案 1 :(得分:0)
yoape答案确实很好,应该从客户端需要从服务外部了解分区信息的情况下考虑。但这表明不可能从服务本身内部进行。
问题是,它要求从服务本身中获取此信息,并且有可能获得如下所示的分区信息。
假设您有一个像这样的StatefulService:
class WorkerService : StatelessService {}
在服务中,您可以获取如下分区信息:
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;
}
Singleton与默认值相同,两者都使用分区的ID。