Přehled serializace výjimek vzdálené komunikace
Serializace založená na BinaryFormatter není zabezpečená, proto ke zpracování dat nepoužívejte BinaryFormatter. Další informace o dopadech na zabezpečení najdete v tématu Rizika deserializace při použití BinaryFormatter a souvisejících typů.
Azure Service Fabric k serializaci výjimek použil BinaryFormatter. Počínaje verzí ServiceFabric v9.0 je jako opt-in k dispozici serializace založená na kontraktech dat pro výjimky vzdálené komunikace. Doporučujeme, abyste se rozhodli pro serializaci výjimky vzdálené komunikace DataContract podle kroků v tomto článku.
Podpora serializace výjimek vzdálené komunikace založené na BinaryFormatter bude v budoucnu zastaralá.
Povolení serializace kontraktů dat pro výjimky vzdálené komunikace
Poznámka:
Serializace kontraktů dat pro výjimky vzdálené komunikace je k dispozici pouze pro vzdálené komunikace V2/V2_1 služby.
Povolení serializace kontraktů dat pro výjimky vzdálené komunikace:
Povolte serializaci výjimky vzdálené komunikace data na straně služby pomocí
FabricTransportRemotingListenerSettings.ExceptionSerializationTechnique
při vytváření naslouchacího procesu vzdálené komunikace.Bezstavová služba
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
Chcete-li povolit serializaci výjimky vzdálené komunikace DataContract ve službě actor, přepsáníCreateServiceReplicaListeners()
rozšířenímActorService
.protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new List<ServiceReplicaListener> { new ServiceReplicaListener(_ => { return new FabricTransportActorServiceRemotingListener( this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }); }, "MyActorServiceEndpointV2") }; }
Pokud má původní výjimka více úrovní vnitřních výjimek, můžete řídit počet úrovní vnitřních výjimek, které mají být serializovány nastavením
FabricTransportRemotingListenerSettings.RemotingExceptionDepth
.Povolte serializaci výjimky vzdálené komunikace data v klientovi pomocí
FabricTransportRemotingSettings.ExceptionDeserializationTechnique
při vytváření objektu pro vytváření klienta.Vytvoření 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); });
Serializace výjimky vzdálené komunikace DataContract převede výjimku na objekt pro přenos dat (DTO) na straně služby. DTO se převede zpět na výjimku na straně klienta. Uživatelé se musí zaregistrovat
ExceptionConvertor
k převodu požadovaných výjimek na objekty DTO a naopak.Architektura implementuje převody pro následující seznam výjimek. Pokud kód uživatelské služby závisí na výjimkách mimo následující seznam pro zpracování opakování a zpracování výjimek, uživatelé musí pro tyto výjimky implementovat a zaregistrovat převodce.
- Všechny výjimky Service Fabric odvozené od
System.Fabric.FabricException
- SystemExceptions odvozené z
System.SystemException
- System.AccessViolationException
- System.AppDomainUnloadedException
- System.ArgumentException
- System.AritmeticException
- 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
- Všechny výjimky Service Fabric odvozené od
Ukázková implementace převodu na straně služby pro vlastní výjimku
Následující příklad je odkaz IExceptionConvertor
implementace na straně služby a klienta pro dobře známý typ výjimky, 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
implementace na straně služby :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; } }
Skutečná výjimka zjištěná během provádění volání vzdálené komunikace je předána jako vstup do TryConvertToServiceException
. Pokud je typ výjimky dobře známý, TryConvertToServiceException
měl by převést původní výjimku na ServiceException
a vrátit ji jako výstupní parametr. Hodnota true by měla být vrácena, pokud původní typ výjimky je dobře známý a původní výjimka je úspěšně převedena na ServiceException
. V opačném případě je hodnota false.
Seznam vnitřních výjimek na aktuální úrovni by měl vrátit GetInnerExceptions()
.
IExceptionConvertor
implementace na straně klienta :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
je předán jako parametr TryConvertFromServiceException
spolu s převedeným innerException[s]
. Je-li skutečný typ výjimky , ServiceException.ActualExceptionType
je známý, convertor by měl vytvořit skutečný objekt výjimky z ServiceException
a innerException[s]
.
IExceptionConvertor
registrace na straně služby :Chcete-li registrovat převodce,
CreateServiceInstanceListeners
musí být přepsán a seznamIExceptionConvertor
tříd musí být předán při vytvářeníRemotingListener
instance.Bezstavová služba
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
registrace na straně klienta :Chcete-li zaregistrovat převodce, musí být při vytváření
ClientFactory
instance předán seznamIExceptionConvertor
tříd.Vytvoření serviceProxyFactory
var serviceProxyFactory = new ServiceProxyFactory( (callbackClient) => { return new FabricTransportServiceRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Vytvoření objektu ActorProxyFactory
var actorProxyFactory = new ActorProxyFactory( (callbackClient) => { return new FabricTransportActorRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Poznámka:
Pokud architektura najde převéstel výjimky, převedená (skutečná) výjimka je zabalena uvnitř AggregateException
a je vyvolána v rozhraní API vzdálené komunikace (proxy). Pokud se rozhraní nepodaří najít převéstel, pak ServiceException
, který obsahuje všechny podrobnosti o skutečné výjimce, je zabalen uvnitř AggregateException
a je vyvolán.
Upgrade existující služby, aby bylo možné povolit serializaci kontraktů dat pro výjimky vzdálené komunikace
Existující služby musí při upgradu postupovat podle následujícího pořadí (Služba jako první). Selháním tohoto pořadí může dojít k nesprávnému chování v logice opakování a zpracování výjimek.
Implementujte třídy na straně
ExceptionConvertor
služby pro požadované výjimky, pokud existuje. Aktualizujte logiku registrace naslouchacího procesu vzdálené komunikaceIExceptionConvertor
pomocíExceptionSerializationTechnique
seznamu tříd. Upgradujte existující službu, aby se použily změny serializace výjimek.Implementujte třídy na straně
ExceptionConvertor
klienta pro požadované výjimky, pokud existuje. Aktualizujte logiku vytváření ProxyFactory pomocíExceptionSerializationTechnique
seznamu tříd a seznamemIExceptionConvertor
tříd. Upgradujte existujícího klienta, aby použil změny serializace výjimek.