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


A kivételhiba-szerializálás újraegyezésének áttekintése

A BinaryFormatter-alapú szerializálás nem biztonságos, ezért ne használja a BinaryFormattert adatfeldolgozáshoz. 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álatakor.

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és-alapú 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ást.

A BinaryFormatter-alapú remoting kivétel szerializálásának támogatása a jövőben elavulttá válik.

Adatszerződés szerializálásának engedélyezése a kivételek újraegyenlítéséhez

Megjegyzés

Az adatszerződés szerializálása a kivételek újraegyenlítéséhez csak a V2/V2_1-szolgáltatások újraindításához érhető el.

Adatszerződés szerializálásának engedélyezése a kivételek újraegyenlítéséhez:

  1. Engedélyezze a DataContract-remoting kivétel szerializálását a szolgáltatásoldalonFabricTransportRemotingListenerSettings.ExceptionSerializationTechnique a remoting figyelő létrehozása során.

    • Állapot nélküli szolgáltatás

      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")
          };
      }
      
    • Aktorszolgáltatás
      Ha engedélyezni szeretné a DataContract-kivétel szerializálását az aktorszolgáltatáson, felülbírálja a következőt CreateServiceReplicaListeners()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 szintből áll, 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élenFabricTransportRemotingSettings.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);
      });
      
    • AktorProxyFactory

      var actorProxyFactory = new ActorProxyFactory(
      (callbackClient) =>
      {
          return new FabricTransportActorRemotingClientFactory(
              new FabricTransportRemotingSettings
              {
                  ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default,
              },
              callbackClient);
      });
      
  3. A DataContract-remoting kivétel szerializálása a kivételt a szolgáltatásoldalon lévő adatátviteli objektummá (DTO) alakítja át. A DTO vissza lesz konvertálva egy kivételre az ügyféloldalon. 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 konvertálókat 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.

    • Az összes Service Fabric-kivétel, amely a System.Fabric.FabricException
    • SystemExceptions származtatása 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ó mintaimplementációja egyéni kivételhez

Az alábbi példa egy jól ismert kivételtípusra CustomExceptionhivatkozik IExceptionConvertor a szolgáltatás- és ügyféloldalon.

  • 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 oldalon:

    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 következőnek TryConvertToServiceException: . Ha a kivétel típusa jól ismert, konvertálja az eredeti kivételt értékreServiceException, TryConvertToServiceException és adja vissza out paraméterként. Igaz értéket kell visszaadni, ha az eredeti kivételtípus jól ismert, és az eredeti kivétel sikeresen konvertálva ServiceExceptionlett. Ellenkező esetben az érték hamis.

Az aktuális szinten lévő belső kivételek listáját a függvénynek kell visszaadnia 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ált innerException[s]paraméterrel együtt. Ha a tényleges kivételtípus () ServiceException.ActualExceptionTypeismert, a konvertálónak létre kell hoznia egy tényleges kivételobjektumot a és innerException[s]a fájlbólServiceException.

  • IExceptionConvertor regisztráció a Szolgáltatás oldalon:

    A konvertálók CreateServiceInstanceListeners regisztrálásához felül kell bírálni, és a példány létrehozásakor át kell adni az RemotingListener osztályok listájátIExceptionConvertor.

    • Állapot nélküli szolgáltatás

      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")
          };
      }
      
    • Aktorszolgáltatás

      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 a példány létrehozásakor át kell adni az ClientFactory osztályok listájátIExceptionConvertor.

    • 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(),
              });
      });
      

Megjegyzés

Ha a keretrendszer megtalálja a kivétel konvertálóját, a konvertált (tényleges) kivétel be van burkolva AggregateException , és a rendszer a remoting API-hoz (proxyhoz) kerül. Ha a keretrendszer nem találja a konvertáló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 újraegyezéséhez

A frissítéshez a meglévő szolgáltatásoknak a következő sorrendet kell követnie (először a szolgáltatást). Ha nem követi ezt a sorrendet, az helytelen működést eredményezhet az újrapróbálkozások logikájában és a kivételkezelésben.

  1. Implementálja a szolgáltatásoldaliExceptionConvertor osztályokat a kívánt kivételekhez, ha vannak ilyenek. Frissítse a visszatartó figyelő regisztrációs logikáját a és az osztályok listájával ExceptionSerializationTechniqueIExceptionConvertor. Frissítse a meglévő szolgáltatást a kivételszerializálási módosítások alkalmazásához.

  2. Implementálja az ügyféloldaliExceptionConvertor osztályokat a kívánt kivételekhez, ha vannak ilyenek. Frissítse a ProxyFactory létrehozási logikáját a és az osztályok listájával ExceptionSerializationTechniqueIExceptionConvertor . Frissítse a meglévő ügyfelet a kivétel szerializálási módosításainak alkalmazásához.

Következő lépések