ServiceFabric: сервис не существует во время развертывания - PullRequest
0 голосов
/ 24 октября 2018

У меня есть система, использующая сервисную фабрику.Все в порядке, за исключением того, что во время публикации службы служба недоступна, и любые разрешения возвращают ошибку.

Это ожидается, однако было бы неплохо, если бы в течение этого времени вместо этого просто ожидали вызовы или тайм-аут.В это время мои журналы ошибок иногда заполняются 200K строк с той же ошибкой.

Мне нужен какой-нибудь код, подобный следующему, однако, куда он пойдет?

public async Task Execute(Func<Task> action)
{
    try
    {
        action()
            .ConfigureAwait(false);
    }
    catch (FabricServiceNotFoundException ex)
    {
        await Task.Delay(TimeSpan.FromSeconds(??))
            .ConfigureAwait(false);

        action()
            .ConfigureAwait(false);
    }

}

Ошибка:

System.Fabric.FabricServiceNotFoundException: Service does not exist. ---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80071BCD
   at System.Fabric.Interop.NativeClient.IFabricServiceManagementClient6.EndResolveServicePartition(IFabricAsyncOperationContext context)
   at System.Fabric.FabricClient.ServiceManagementClient.ResolveServicePartitionEndWrapper(IFabricAsyncOperationContext context)
   at System.Fabric.Interop.AsyncCallOutAdapter2`1.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously)
   --- End of inner exception stack trace ---
   at Microsoft.ServiceFabric.Services.Client.ServicePartitionResolver.ResolveHelperAsync(Func`5 resolveFunc, ResolvedServicePartition previousRsp, TimeSpan resolveTimeout, TimeSpan maxRetryInterval, CancellationToken cancellationToken, Uri serviceUri)
   at Microsoft.ServiceFabric.Services.Communication.Client.CommunicationClientFactoryBase`1.CreateClientWithRetriesAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, String listenerName, OperationRetrySettings retrySettings, Boolean doInitialResolve, CancellationToken cancellationToken)
   at Microsoft.ServiceFabric.Services.Communication.Client.CommunicationClientFactoryBase`1.GetClientAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplica, String listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
   at Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Client.FabricTransportServiceRemotingClientFactory.GetClientAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, String listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
   at Microsoft.ServiceFabric.Services.Communication.Client.ServicePartitionClient`1.GetCommunicationClientAsync(CancellationToken cancellationToken)
   at Microsoft.ServiceFabric.Services.Communication.Client.ServicePartitionClient`1.InvokeWithRetryAsync[TResult](Func`2 func, CancellationToken cancellationToken, Type[] doNotRetryExceptionTypes)
   at Microsoft.ServiceFabric.Services.Remoting.V2.Client.ServiceRemotingPartitionClient.InvokeAsync(IServiceRemotingRequestMessage remotingRequestMessage, String methodName, CancellationToken cancellationToken)
   at Microsoft.ServiceFabric.Services.Remoting.Builder.ProxyBase.InvokeAsyncV2(Int32 interfaceId, Int32 methodId, String methodName, IServiceRemotingRequestMessageBody requestMsgBodyValue, CancellationToken cancellationToken)
   at Microsoft.ServiceFabric.Services.Remoting.Builder.ProxyBase.ContinueWithResultV2[TRetval](Int32 interfaceId, Int32 methodId, Task`1 task)

1 Ответ

0 голосов
/ 24 октября 2018

Как и ожидалось, Service Fabric должна завершить работу службы, чтобы запустить новую версию, это вызовет временную ошибку, подобную той, которую вы получили.

По умолчанию API-интерфейсы удаленного взаимодействия уже имеют логику повторных попытоквстроенный, из документов :

Прокси-сервер службы обрабатывает все исключения отработки отказа для служебного раздела, для которого он создан.Он повторно разрешает конечные точки, если есть исключения при отказе (не переходные исключения), и повторяет вызов с правильной конечной точкой.Число повторных попыток для исключений аварийного переключения неопределенно.Если возникают временные исключения, прокси-сервер повторяет вызов.

При этом вам не нужно добавлять дополнительную логику повторных попыток, возможно, вам следует попытаться настроить OperationRetrySettings для лучшегообработка этих повторных попыток.

Если проблема не решается, и вы все еще хотите добавить логику в свой код, самый простой способ справиться с ней - использовать библиотеку обработки кратковременных сбоев, такую ​​как Polly, что-то вроде ниже:

   var policy = Policy
                 .Handle<FabricServiceNotFoundException>()
                 .WaitAndRetry(new[]
                 {
                   TimeSpan.FromSeconds(1),
                   TimeSpan.FromSeconds(2),
                   TimeSpan.FromSeconds(3)
                 });

   policy.Execute(() => DoSomething());

В этом примере вы делаете экспоненциальный откат между повторными попытками, если число вызовов слишком велико, я бы рекомендовал вместо этого реализовать подход с автоматическим выключателем.

...