Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Serializacja oparta na binaryFormatter nie jest bezpieczna, więc nie używaj klasy BinaryFormatter do przetwarzania danych. Aby uzyskać więcej informacji dotyczących implikacji zabezpieczeń, zobacz Ryzyka deserializacji przy użyciu BinaryFormattera i powiązanych typów.
Usługa Azure Service Fabric używa narzędzia BinaryFormatter do serializacji wyjątków. Począwszy od wersji 9.0 ServiceFabric, serializacja oparta na kontrakcie danych dla zdalnych wyjątków jest dostępna jako funkcja opcjonalna. Zachęcamy do wyboru serializacji wyjątków zdalnych za pomocą DataContract, wykonując kroki opisane w tym artykule.
Obsługa serializacji wyjątków remoting opartych na programie BinaryFormatter zostanie wycofana w przyszłości.
Włącz serializację kontraktu danych dla wyjątków zdalnych
Uwaga
Serializacja kontraktu danych dla wyjątków zdalnej komunikacji jest dostępna tylko w przypadku usług zdalnej komunikacji V2/V2_1.
Aby włączyć serializację danych kontraktowych dla wyjątków zdalnych wywołań:
Włącz serializację wyjątków komunikacji zdalnej DataContract po stronie usługi przy użyciu
FabricTransportRemotingListenerSettings.ExceptionSerializationTechnique
podczas tworzenia odbiornika komunikacji zdalnej.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") }; }
AktorService
Aby włączyć serializację wyjątków zdalnego wywołania w DataContract na usłudze aktora, nadpisz metodęCreateServiceReplicaListeners()
poprzez rozszerzenieActorService
.protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new List<ServiceReplicaListener> { new ServiceReplicaListener(_ => { return new FabricTransportActorServiceRemotingListener( this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }); }, "MyActorServiceEndpointV2") }; }
Jeśli oryginalny wyjątek ma wiele poziomów wyjątków wewnętrznych, można kontrolować liczbę poziomów wyjątków wewnętrznych, które mają być serializowane, ustawiając wartość
FabricTransportRemotingListenerSettings.RemotingExceptionDepth
.Włącz serializację wyjątków przekazywania zdalnego DataContract na kliencie przy użyciu
FabricTransportRemotingSettings.ExceptionDeserializationTechnique
podczas tworzenia fabryki klienta.Tworzenie ServiceProxyFactory
var serviceProxyFactory = new ServiceProxyFactory( (callbackClient) => { return new FabricTransportServiceRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient); });
AktorProxyFactory
var actorProxyFactory = new ActorProxyFactory( (callbackClient) => { return new FabricTransportActorRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient); });
Serializacja wyjątków zdalnej komunikacji DataContract konwertuje wyjątek na obiekt transferu danych (DTO) po stronie usługi. Obiekt DTO jest konwertowany z powrotem na wyjątek po stronie klienta. Użytkownicy muszą zarejestrować się
ExceptionConvertor
, aby przekonwertować żądane wyjątki na obiekty DTO i na odwrót.Struktura implementuje konwertery dla następującej listy wyjątków. Jeśli kod usługi użytkownika zależy od wyjątków spoza poniższej listy na potrzeby implementacji ponawiania i obsługi wyjątków, użytkownicy muszą implementować i rejestrować konwertery dla takich wyjątków.
- Wszystkie wyjątki usługi Service Fabric pochodzące z
System.Fabric.FabricException
- Wyjątek SystemExceptions pochodzący z
System.SystemException
- System.AccessViolationException (Wyjątek naruszenia dostępu)
- 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 (Nieobsługiwany wyjątek)
- 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
- Wszystkie wyjątki usługi Service Fabric pochodzące z
Przykładowa implementacja konwertora po stronie usługi dla wyjątku niestandardowego
Poniższy przykład to implementacja referencyjna IExceptionConvertor
po stronie usługi i klienta dla dobrze znanego typu wyjątku . 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
implementacja po stronie usługi :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; } }
Rzeczywisty wyjątek zaobserwowany podczas wykonywania zdalnego połączenia jest przekazywany jako dane wejściowe do TryConvertToServiceException
. Jeśli typ wyjątku jest dobrze znany, TryConvertToServiceException
należy przekonwertować oryginalny wyjątek na ServiceException
i zwrócić go jako parametr wyjściowy. Wartość true powinna zostać zwrócona, jeśli oryginalny typ wyjątku jest dobrze znany, a oryginalny wyjątek został pomyślnie przekonwertowany na ServiceException
. W przeciwnym razie wartość to fałsz.
Lista wyjątków wewnętrznych na bieżącym poziomie ma być zwracana przez GetInnerExceptions()
.
IExceptionConvertor
implementacja po stronie 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
jest przekazywane jako parametr do TryConvertFromServiceException
wraz z przekonwertowanym elementem innerException[s]
. Jeśli rzeczywisty typ wyjątku, ServiceException.ActualExceptionType
, jest znany, konwertujący powinien utworzyć rzeczywisty obiekt wyjątku z ServiceException
i innerException[s]
.
IExceptionConvertor
rejestracja po stronie usługi :Aby zarejestrować konwertery,
CreateServiceInstanceListeners
musi być nadpisane, a lista klasIExceptionConvertor
należy przekazać podczas tworzenia wystąpieniaRemotingListener
.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") }; }
AktorService
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
rejestracja po stronie klienta :Aby zarejestrować
IExceptionConvertor
konwertery, lista klas musi zostać przekazana podczas tworzenia wystąpieniaClientFactory
.Tworzenie ServiceProxyFactory
var serviceProxyFactory = new ServiceProxyFactory( (callbackClient) => { return new FabricTransportServiceRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Tworzenie aktoraProxyFactory
var actorProxyFactory = new ActorProxyFactory( (callbackClient) => { return new FabricTransportActorRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Uwaga
Jeśli framework znajdzie konwerter dla wyjątku, przekonwertowany (rzeczywisty) wyjątek jest opakowany wewnątrz AggregateException
i jest zgłaszany do zdalnego interfejsu API (proxy). Jeśli framework nie może odnaleźć konwertora, to ServiceException
, który zawiera wszystkie szczegóły rzeczywistego wyjątku, jest opakowany wewnątrz AggregateException
i zostaje zgłoszony.
Uaktualnij istniejącą usługę, aby umożliwić serializację kontraktów danych do wyjątków zdalnych.
Aby zaktualizować, istniejące usługi muszą postępować według następującej kolejności (Najpierw usługa). Niepowodzenie wykonania tej kolejności może spowodować niewłaściwe zachowanie logiki ponawiania prób i obsługi wyjątków.
Zaimplementuj klasy po stronie usługi dla żądanych wyjątków, jeśli są potrzebne. Zaktualizuj logikę rejestracji odbiornika zdalnego za pomocą
ExceptionSerializationTechnique
i listyIExceptionConvertor
klas. Uaktualnij istniejącą usługę, aby zastosować zmiany serializacji wyjątków.Zaimplementuj klasy po stronie
ExceptionConvertor
klienta dla żądanych wyjątków, jeśli istnieją. Zaktualizuj logikę tworzenia ProxyFactory zExceptionSerializationTechnique
i listą klasIExceptionConvertor
. Uaktualnij istniejącego klienta, aby zastosować zmiany serializacji wyjątków.