未找到 TargetReplicaSelector RandomSecondaryReplica 端点
TargetReplicaSelector RandomSecondaryReplica endpoint not found
找不到与指定 TargetReplicaSelector 匹配的服务“{serviceB}”分区“{guid}”的端点:'RandomSecondaryReplica'
这个错误并不总是会出现,但有时会出现。
我正在从另一个有状态服务 A 调用有状态服务 B,使用服务远程处理,请求随机辅助副本,以访问写入主副本的状态。
我可以在资源管理器中看到分区在那里并且显示正常,并且它有一个主分区和两个 ActiveSecondaries。
服务 B 具有以下内容:
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new[] { new ServiceReplicaListener(context =>
this.CreateServiceRemotingListener(context), listenOnSecondary: true) };
}
我通过这个得到所有的分区:
return Enumerable.Range(0, PartitionConstants.Partitions).Select(x =>
ServiceProxy.Create<IServiceB>(
ServiceBUri,
new ServicePartitionKey(x),
TargetReplicaSelector.RandomSecondaryReplica));
并且整体设置必须正常,因为有时它确实有效。我知道主服务器正在响应,因为我已经在那里保存了状态。
那么,当我实际上可以看到那里的分区和辅助副本时,是什么导致了这个错误?
Update1 : 重新启动调用服务使连接工作。但是他们一起开始,在 运行 和工作之后,问题仍然存在,直到我重新启动。怎么样?
Update2 : 这发生在整个集群启动时。在启动时,Service A primaries 调用 Service B primaries 进行一些注册。 A 在执行此操作之前轮询 B 以了解它已启动其内部状态。
然后当这个完成后,服务A继续检查它的内部状态是否需要更新,如果需要,它将再次调用服务B来检索状态。由于它不会对 B 状态进行任何写入,因此它调用辅助副本。这是找不到端点的时候。
当我重新启动服务 A 时,找到端点。
会不会是初选正常,副选还不行?
我怎样才能确定这一点? 是否有一些我可以访问的服务结构 class 知道如果我调用它是否会找到辅助服务器?
使用 service primer found here,解决了这个问题。调用时似乎并非所有分区副本都准备就绪。
基本上,它所做的是通过 FabricClient 计算所有分区的所有副本,直到找到预期的计数。
代码如下:
public async Task WaitForStatefulService(Uri serviceInstanceUri, CancellationToken token)
{
StatefulServiceDescription description =
await this.Client.ServiceManager.GetServiceDescriptionAsync(serviceInstanceUri) as StatefulServiceDescription;
int targetTotalReplicas = description.TargetReplicaSetSize;
if (description.PartitionSchemeDescription is UniformInt64RangePartitionSchemeDescription)
{
targetTotalReplicas *= ((UniformInt64RangePartitionSchemeDescription)description.PartitionSchemeDescription).PartitionCount;
}
ServicePartitionList partitions = await this.Client.QueryManager.GetPartitionListAsync(serviceInstanceUri);
int replicaTotal = 0;
while (replicaTotal < targetTotalReplicas && !token.IsCancellationRequested)
{
await Task.Delay(this.interval);
//ServiceEventSource.Current.ServiceMessage(this, "CountyService waiting for National Service to come up.");
replicaTotal = 0;
foreach (Partition partition in partitions)
{
ServiceReplicaList replicaList = await this.Client.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id);
replicaTotal += replicaList.Count(x => x.ReplicaStatus == System.Fabric.Query.ServiceReplicaStatus.Ready);
}
}
}
找不到与指定 TargetReplicaSelector 匹配的服务“{serviceB}”分区“{guid}”的端点:'RandomSecondaryReplica'
这个错误并不总是会出现,但有时会出现。
我正在从另一个有状态服务 A 调用有状态服务 B,使用服务远程处理,请求随机辅助副本,以访问写入主副本的状态。
我可以在资源管理器中看到分区在那里并且显示正常,并且它有一个主分区和两个 ActiveSecondaries。
服务 B 具有以下内容:
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new[] { new ServiceReplicaListener(context =>
this.CreateServiceRemotingListener(context), listenOnSecondary: true) };
}
我通过这个得到所有的分区:
return Enumerable.Range(0, PartitionConstants.Partitions).Select(x =>
ServiceProxy.Create<IServiceB>(
ServiceBUri,
new ServicePartitionKey(x),
TargetReplicaSelector.RandomSecondaryReplica));
并且整体设置必须正常,因为有时它确实有效。我知道主服务器正在响应,因为我已经在那里保存了状态。
那么,当我实际上可以看到那里的分区和辅助副本时,是什么导致了这个错误?
Update1 : 重新启动调用服务使连接工作。但是他们一起开始,在 运行 和工作之后,问题仍然存在,直到我重新启动。怎么样?
Update2 : 这发生在整个集群启动时。在启动时,Service A primaries 调用 Service B primaries 进行一些注册。 A 在执行此操作之前轮询 B 以了解它已启动其内部状态。
然后当这个完成后,服务A继续检查它的内部状态是否需要更新,如果需要,它将再次调用服务B来检索状态。由于它不会对 B 状态进行任何写入,因此它调用辅助副本。这是找不到端点的时候。 当我重新启动服务 A 时,找到端点。
会不会是初选正常,副选还不行? 我怎样才能确定这一点? 是否有一些我可以访问的服务结构 class 知道如果我调用它是否会找到辅助服务器?
使用 service primer found here,解决了这个问题。调用时似乎并非所有分区副本都准备就绪。
基本上,它所做的是通过 FabricClient 计算所有分区的所有副本,直到找到预期的计数。
代码如下:
public async Task WaitForStatefulService(Uri serviceInstanceUri, CancellationToken token)
{
StatefulServiceDescription description =
await this.Client.ServiceManager.GetServiceDescriptionAsync(serviceInstanceUri) as StatefulServiceDescription;
int targetTotalReplicas = description.TargetReplicaSetSize;
if (description.PartitionSchemeDescription is UniformInt64RangePartitionSchemeDescription)
{
targetTotalReplicas *= ((UniformInt64RangePartitionSchemeDescription)description.PartitionSchemeDescription).PartitionCount;
}
ServicePartitionList partitions = await this.Client.QueryManager.GetPartitionListAsync(serviceInstanceUri);
int replicaTotal = 0;
while (replicaTotal < targetTotalReplicas && !token.IsCancellationRequested)
{
await Task.Delay(this.interval);
//ServiceEventSource.Current.ServiceMessage(this, "CountyService waiting for National Service to come up.");
replicaTotal = 0;
foreach (Partition partition in partitions)
{
ServiceReplicaList replicaList = await this.Client.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id);
replicaTotal += replicaList.Count(x => x.ReplicaStatus == System.Fabric.Query.ServiceReplicaStatus.Ready);
}
}
}