找不到该服务的端点' {serviceB}'分区' {guid}'与指定的TargetReplicaSelector匹配:' 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:重新启动呼叫服务使连接正常工作。但是他们一起开始,并且在两个人一直运行和工作之后,问题仍然存在,直到我重新开始。 Howcome?
Update2:启动整个群集时会发生这种情况。在启动时,服务A初选称服务B初选为一些注册。在进行此操作之前,轮询B知道它已启动其内部状态。
然后,当完成此操作后,服务A继续检查其内部状态是否需要更新,如果是,则它将再次调用服务B以检索状态。由于它不会对B状态进行任何写入,因此它会调用辅助副本。这是在找不到端点的时候。 当我重新启动服务A时,找到了端点。
可能是初选工作正常,但辅助设备还不行吗? 我怎样才能确定这一点? 我是否可以访问某些服务架构类,以了解是否可以找到辅助服务器?
答案 0 :(得分:1)
使用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);
}
}
}