A kivétel szerializálásának újbóli létrehozása – áttekintés
A BinaryFormatter-alapú szerializálás nem biztonságos, ezért ne használja a BinaryFormattert adatfeldolgozásra. A biztonsági következményekkel kapcsolatos további információkért lásd : Deszerializálási kockázatok a BinaryFormatter és a kapcsolódó típusok használata során.
Az Azure Service Fabric a BinaryFormattert használta a kivételek szerializálásához. A ServiceFabric 9.0-s verziótól kezdve az adatszerződésen alapuló szerializálás a kivételek újraegyeztetési funkciójaként érhető el. Javasoljuk, hogy a jelen cikk lépéseit követve válassza a DataContract kivétel-szerializálását.
A BinaryFormatter-alapú remoting exception szerializálás támogatása a jövőben megszűnik.
Adatszerződés szerializálásának engedélyezése a kivételek újraírásához
Feljegyzés
Az adatszerződések szerializálása a kivételek újraegyesítéséhez csak a V2/V2_1 szolgáltatások újbóli létrehozásához érhető el.
Adatszerződés szerializálásának engedélyezése a kivételek újraírásához:
Engedélyezze a DataContract-remoting exception szerializálását a szolgáltatás oldalán
FabricTransportRemotingListenerSettings.ExceptionSerializationTechnique
az újraindító figyelő létrehozása során.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
Ha engedélyezni szeretné a DataContract-remoting kivétel szerializálását az aktorszolgáltatáson, felülbírálástCreateServiceReplicaListeners()
kell elvégeznie a kiterjesztésselActorService
.protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new List<ServiceReplicaListener> { new ServiceReplicaListener(_ => { return new FabricTransportActorServiceRemotingListener( this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }); }, "MyActorServiceEndpointV2") }; }
Ha az eredeti kivétel több belső kivételszinttel rendelkezik, a beállítással
FabricTransportRemotingListenerSettings.RemotingExceptionDepth
szabályozhatja a szerializálandó belső kivételek szintjeinek számát.Engedélyezze a DataContract kivétel szerializálását az ügyfélen
FabricTransportRemotingSettings.ExceptionDeserializationTechnique
az ügyfél-előállító létrehozása során.ServiceProxyFactory létrehozása
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); });
A DataContract remoting exception szerializálása a szolgáltatásoldalon lévő adatátviteli objektummá (DTO) konvertál egy kivételt. A DTO az ügyféloldalon kivételként lesz konvertálva. A felhasználóknak regisztrálniuk
ExceptionConvertor
kell a kívánt kivételek DTO-objektumokká való konvertálásához, és fordítva.A keretrendszer konvertorokat implementál a kivételek alábbi listájához. Ha a felhasználói szolgáltatás kódja az újrapróbálkozási és kivételkezelési listán kívüli kivételektől függ, a felhasználóknak konvertorokat kell implementálniuk és regisztrálniuk az ilyen kivételekhez.
- Minden Service Fabric-kivétel, amely a
System.Fabric.FabricException
- SystemExceptions származik
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
- Minden Service Fabric-kivétel, amely a
Szolgáltatásoldali átalakító mintaalkalmazása egyéni kivételhez
Az alábbi példa egy jól ismert kivételtípus CustomException
szolgáltatás- és ügyféloldali implementációjára mutat.IExceptionConvertor
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
implementáció a szolgáltatás oldalán: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; } }
A rendszer a visszahívás végrehajtása során megfigyelt tényleges kivételt adja át bemenetként a programnak TryConvertToServiceException
. Ha a kivétel típusa jól ismert, TryConvertToServiceException
konvertálja az eredeti kivételt ServiceException
kimenő paraméterként, és adja vissza. Igaz értéket kell visszaadni, ha az eredeti kivételtípus jól ismert, és az eredeti kivételt sikeresen konvertálja ServiceException
a rendszer. Ellenkező esetben az érték hamis.
A belső kivételek listáját az aktuális szinten kell visszaadni GetInnerExceptions()
.
IExceptionConvertor
implementáció az ügyféloldalon :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
paraméterként lesz átadva a TryConvertFromServiceException
konvertálással innerException[s]
együtt. Ha a tényleges kivétel típusa ismert, ServiceException.ActualExceptionType
akkor a konvertálónak létre kell hoznia egy tényleges kivételobjektumot a következőből ServiceException
: és innerException[s]
.
IExceptionConvertor
regisztráció a szolgáltatás oldalán:A konvertálók regisztrálásához felül kell bírálni,
CreateServiceInstanceListeners
és az osztályok listájátIExceptionConvertor
át kell adni aRemotingListener
példány létrehozásakor.StatelessService
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
regisztráció az ügyféloldalon :A konvertálók regisztrálásához az osztályok listáját
IExceptionConvertor
át kell adni aClientFactory
példány létrehozásakor.ServiceProxyFactory létrehozása
var serviceProxyFactory = new ServiceProxyFactory( (callbackClient) => { return new FabricTransportServiceRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
ActorProxyFactory létrehozása
var actorProxyFactory = new ActorProxyFactory( (callbackClient) => { return new FabricTransportActorRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Feljegyzés
Ha a keretrendszer megkeresi a kivétel konvertálóját, a konvertált (tényleges) kivétel be van csomagolva AggregateException
, és a rendszer az újraküldési API-hoz (proxyhoz) kerül. Ha a keretrendszer nem találja a átalakítót, akkor ServiceException
a rendszer a tényleges kivétel összes részletét tartalmazza, becsomagolódik AggregateException
és eldobja.
Meglévő szolgáltatás frissítése az adatszerződés szerializálásának engedélyezéséhez a kivételek újraegyesítéséhez
A frissítéshez a meglévő szolgáltatásoknak az alábbi sorrendet kell követnie (először a szolgáltatást). Ha nem követi ezt a sorrendet, az újrapróbálkozások logikájában és kivételkezelésében helytelenül viselkedhet.
Implementálja a szolgáltatásoldali
ExceptionConvertor
osztályokat a kívánt kivételekhez, ha vannak ilyenek. Frissítse az újraegyesítő figyelő regisztrációs logikájátExceptionSerializationTechnique
és az osztályok listájátIExceptionConvertor
. Frissítse a meglévő szolgáltatást a kivétel szerializálási módosításainak alkalmazásához.Implementálja az ügyféloldali
ExceptionConvertor
osztályokat a kívánt kivételekhez, ha vannak ilyenek. Frissítse a ProxyFactory létrehozási logikájátExceptionSerializationTechnique
és az osztályok listájátIExceptionConvertor
. Frissítse a meglévő ügyfelet a kivétel szerializálási módosításainak alkalmazásához.