Megosztás a következőn keresztül:


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:

  1. 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ást CreateServiceReplicaListeners() kell elvégeznie a kiterjesztéssel ActorService.

      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.RemotingExceptionDepthszabályozhatja a szerializálandó belső kivételek szintjeinek számát.

  2. 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);
      });
      
  3. 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

Szolgáltatásoldali átalakító mintaalkalmazása egyéni kivételhez

Az alábbi példa egy jól ismert kivételtípus CustomExceptionszolgá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 ServiceExceptiona 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.ActualExceptionTypeakkor 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át IExceptionConvertor át kell adni a RemotingListener 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 a ClientFactory 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 ServiceExceptiona 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.

  1. 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át ExceptionSerializationTechnique és az osztályok listáját IExceptionConvertor. Frissítse a meglévő szolgáltatást a kivétel szerializálási módosításainak alkalmazásához.

  2. 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át ExceptionSerializationTechnique és az osztályok listáját IExceptionConvertor . Frissítse a meglévő ügyfelet a kivétel szerializálási módosításainak alkalmazásához.

Következő lépések