未找到TargetReplicaSelector RandomSecondaryReplica端点

时间:2017-02-22 12:08:51

标签: azure-service-fabric

找不到该服务的端点' {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时,找到了端点。

可能是初选工作正常,但辅助设备还不行吗? 我怎样才能确定这一点? 我是否可以访问某些服务架构类,以了解是否可以找到辅助服务器?

1 个答案:

答案 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);
                }
            }
        }