未找到 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);
                }
            }
        }