Обзор сериализации исключений удаленного взаимодействия
Сериализация на основе BinaryFormatter не является безопасной, поэтому не используйте BinaryFormatter для обработки данных. Дополнительные сведения о последствиях безопасности см. в разделе Риски десериализации в использовании BinaryFormatter и связанных типов.
В Service Fabric для сериализации исключений использовался BinaryFormatter. Начиная с ServiceFabric версии 9.0 сериализация на основе контракта данных для исключений удаленного взаимодействия предоставляется в качестве выбираемой функции. Рекомендуется выбрать сериализацию исключений удаленного взаимодействия DataContract, выполнив действия, описанные в этой статье.
Поддержка сериализации исключений удаленного взаимодействия на основе BinaryFormatter будет прекращена в будущем.
Включение сериализации данных контракта для исключений удаленного взаимодействия
Примечание.
Сериализация контракта данных для исключений удаленного взаимодействия доступна только для служб удаленного взаимодействия версии 2/V2_1.
Включение сериализации данных контракта для исключений удаленного взаимодействия:
Включите сериализацию исключений удаленного взаимодействия контракта данных на стороне Службы, используя
FabricTransportRemotingListenerSettings.ExceptionSerializationTechnique
при создании прослушивателя удаленного взаимодействия.StatelessService
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() { return new[] { new ServiceInstanceListener(serviceContext => new FabricTransportServiceRemotingListener( serviceContext, this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }), "ServiceEndpointV2") }; }
StatefulService
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new[] { new ServiceReplicaListener(serviceContext => new FabricTransportServiceRemotingListener( serviceContext, this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }), "ServiceEndpointV2") }; }
ActorService
Чтобы включить сериализацию исключений удаленного взаимодействия DataContract в ActorService, заменитеCreateServiceReplicaListeners()
путем расширенияActorService
.protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new List<ServiceReplicaListener> { new ServiceReplicaListener(_ => { return new FabricTransportActorServiceRemotingListener( this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }); }, "MyActorServiceEndpointV2") }; }
Если исходное исключение имеет несколько уровней внутренних исключений, можно управлять количеством уровней внутренних исключений, для которых выполняется сериализация, с помощью параметра
FabricTransportRemotingListenerSettings.RemotingExceptionDepth
.Включение сериализации исключений удаленного взаимодействия DataContract на Клиенте с помощью
FabricTransportRemotingSettings.ExceptionDeserializationTechnique
при создании фабрики клиентов.Создание ServiceProxyFactory
var serviceProxyFactory = new ServiceProxyFactory( (callbackClient) => { return new FabricTransportServiceRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient); });
ActorProxyFactory
var actorProxyFactory = new ActorProxyFactory( (callbackClient) => { return new FabricTransportActorRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient); });
Сериализация удаленного взаимодействия DataContract преобразует исключение в объект передачи данных (DTO) на стороне службы. DTO преобразуется обратно в исключение на стороне клиента. Пользователям необходимо зарегистрировать
ExceptionConvertor
для преобразования требуемых исключений в объекты DTO и наоборот.Платформа реализует преобразователи для следующего списка исключений. Если код пользовательской службы зависит от исключений за пределами приведенного ниже списка для реализации повторных попыток, обработки исключений и т. д., пользователю необходимо реализовать и зарегистрировать преобразователи для таких исключений.
- Все исключения Service Fabric, производные от
System.Fabric.FabricException
- SystemExceptions, производные от
System.SystemException
- System.AccessViolationException
- System.AppDomainUnloadedException
- System.ArgumentException
- System.ArithmeticException
- System.ArrayTypeMismatchException
- System.BadImageFormatException
- System.CannotUnloadAppDomainException
- System.Collections.Generic.KeyNotFoundException
- System.ContextMarshalException
- System.DataMisalignedException
- System.ExecutionEngineException
- System.FormatException
- System.IndexOutOfRangeException
- System.InsufficientExecutionStackException
- System.InvalidCastException
- System.InvalidOperationException
- System.InvalidProgramException
- System.IO.InternalBufferOverflowException
- System.IO.InvalidDataException
- System.IO.IOException
- System.MemberAccessException
- System.MulticastNotSupportedException
- System.NotImplementedException
- System.NotSupportedException
- System.NullReferenceException
- System.OperationCanceledException
- System.OutOfMemoryException
- System.RankException
- System.Reflection.AmbiguousMatchException
- System.Reflection.ReflectionTypeLoadException
- System.Resources.MissingManifestResourceException
- System.Resources.MissingSatelliteAssemblyException
- System.Runtime.InteropServices.ExternalException
- System.Runtime.InteropServices.InvalidComObjectException
- System.Runtime.InteropServices.InvalidOleVariantTypeException
- System.Runtime.InteropServices.MarshalDirectiveException
- System.Runtime.InteropServices.SafeArrayRankMismatchException
- System.Runtime.InteropServices.SafeArrayTypeMismatchException
- System.Runtime.Serialization.SerializationException
- System.StackOverflowException
- System.Threading.AbandonedMutexException
- System.Threading.SemaphoreFullException
- System.Threading.SynchronizationLockException
- System.Threading.ThreadInterruptedException
- System.Threading.ThreadStateException
- System.TimeoutException
- System.TypeInitializationException
- System.TypeLoadException
- System.TypeUnloadedException
- System.UnauthorizedAccessException
- System.ArgumentNullException
- System.IO.FileNotFoundException
- System.IO.DirectoryNotFoundException
- System.ObjectDisposedException
- System.AggregateException
- Все исключения Service Fabric, производные от
Пример реализации преобразователя на стороне службы для пользовательского исключения
Ниже приведен пример реализации IExceptionConvertor
на стороне Службы и Клиента для известного типа исключения, CustomException
.
CustomException
class CustomException : Exception { public CustomException(string message, string field1, string field2) : base(message) { this.Field1 = field1; this.Field2 = field2; } public CustomException(string message, Exception innerEx, string field1, string field2) : base(message, innerEx) { this.Field1 = field1; this.Field2 = field2; } public string Field1 { get; set; } public string Field2 { get; set; } }
реализация
IExceptionConvertor
на стороне Службы:class CustomConvertorService : Microsoft.ServiceFabric.Services.Remoting.V2.Runtime.IExceptionConvertor { public Exception[] GetInnerExceptions(Exception originalException) { return originalException.InnerException == null ? null : new Exception[] { originalException.InnerException }; } public bool TryConvertToServiceException(Exception originalException, out ServiceException serviceException) { serviceException = null; if (originalException is CustomException customEx) { serviceException = new ServiceException(customEx.GetType().FullName, customEx.Message); serviceException.ActualExceptionStackTrace = originalException.StackTrace; serviceException.ActualExceptionData = new Dictionary<string, string>() { { "Field1", customEx.Field1 }, { "Field2", customEx.Field2 }, }; return true; } return false; } }
Фактическое исключение, наблюдаемое во время выполнения вызова удаленного взаимодействия, передается в качестве входных данных в TryConvertToServiceException
. Если тип исключения является хорошо известным, то TryConvertToServiceException
должен преобразовать исходное исключение в ServiceException
и вернуть его в качестве выходного параметра. Значение true должно быть возвращено, если исходный тип исключения хорошо известен, а исходное исключение успешно преобразовано в ServiceException
. В противном случае значение равно false.
GetInnerExceptions()
должен возвращать список внутренних исключений на текущем уровне.
реализация
IExceptionConvertor
на стороне Клиента:class CustomConvertorClient : Microsoft.ServiceFabric.Services.Remoting.V2.Client.IExceptionConvertor { public bool TryConvertFromServiceException(ServiceException serviceException, out Exception actualException) { return this.TryConvertFromServiceException(serviceException, (Exception)null, out actualException); } public bool TryConvertFromServiceException(ServiceException serviceException, Exception innerException, out Exception actualException) { actualException = null; if (serviceException.ActualExceptionType == typeof(CustomException).FullName) { actualException = new CustomException( serviceException.Message, innerException, serviceException.ActualExceptionData["Field1"], serviceException.ActualExceptionData["Field2"]); return true; } return false; } public bool TryConvertFromServiceException(ServiceException serviceException, Exception[] innerExceptions, out Exception actualException) { throw new NotImplementedException(); } }
ServiceException
передается в качестве параметра в TryConvertFromServiceException
вместе с преобразованным innerException[s]
. Если фактический тип исключения, ServiceException.ActualExceptionType
, является известным, то преобразователь должен создать фактический объект исключения из ServiceException
и innerException[s]
.
Регистрация
IExceptionConvertor
на стороне Службы:Чтобы зарегистрировать преобразователи,
CreateServiceInstanceListeners
необходимо переопределить и передать списокIExceptionConvertor
классов во время создания экземпляраRemotingListener
.Служба без отслеживания состояния
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() { return new[] { new ServiceInstanceListener(serviceContext => new FabricTransportServiceRemotingListener( serviceContext, this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }, exceptionConvertors: new[] { new CustomConvertorService(), }), "ServiceEndpointV2") }; }
StatefulService
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new[] { new ServiceReplicaListener(serviceContext => new FabricTransportServiceRemotingListener( serviceContext, this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }, exceptionConvertors: new [] { new CustomConvertorService(), }), "ServiceEndpointV2") }; }
ActorService
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new List<ServiceReplicaListener> { new ServiceReplicaListener(_ => { return new FabricTransportActorServiceRemotingListener( this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }, exceptionConvertors: new[] { new CustomConvertorService(), }); }, "MyActorServiceEndpointV2") }; }
Регистрация
IExceptionConvertor
на стороне клиента:Чтобы зарегистрировать преобразователи, необходимо передать список
IExceptionConvertor
классов при создании экземпляраClientFactory
.Создание ServiceProxyFactory
var serviceProxyFactory = new ServiceProxyFactory( (callbackClient) => { return new FabricTransportServiceRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Создание ActorProxyFactory
var actorProxyFactory = new ActorProxyFactory( (callbackClient) => { return new FabricTransportActorRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Примечание.
Если платформа находит преобразователь для исключения, то преобразованное (фактическое) исключение переносится в AggregateException
и выдается в API удаленного взаимодействия (прокси). Если платформе не удается найти преобразователь, то ServiceException
, содержащее все сведения о фактическом исключении, переносится в AggregateException
и вызывается.
Обновление существующей службы для включения сериализации данных контракта для исключений удаленных взаимодействий
Для обновления существующие службы должны быть указаны в следующем порядке (Сначала служба). Если этот порядок не соблюдается, это может привести к неправильному выполнению логики повторных попыток и обработке исключений.
Реализуйте классы на стороне Службы
ExceptionConvertor
для требуемых исключений (если таковые есть). Обновите логику регистрации прослушивателя удаленного взаимодействия с помощьюExceptionSerializationTechnique
и спискаIExceptionConvertor
классов. Обновление существующей службы для применения изменений сериализации исключений.Реализуйте классы на стороне клиента
ExceptionConvertor
для требуемых исключений (если таковые есть). Обновите логику создания ProxyFactory с помощьюExceptionSerializationTechnique
и спискаIExceptionConvertor
классов. Обновите существующий клиент для применения изменений сериализации исключений.
Следующие шаги
- Веб-API с OWIN в модели Reliable Services
- WCF-based communication stack for Reliable Services (Стек взаимодействия для Reliable Services на основе WCF)
- Secure service remoting communications in a C# service (Защита удаленного взаимодействия в службе C#)