Dela via


Översikt över fjärrkommunikationsfelserialisering

BinaryFormatter-baserad serialisering är inte säker, så använd inte BinaryFormatter för databearbetning. Mer information om säkerhetskonsekvenserna finns i Deserialiseringsrisker vid användning av BinaryFormatter och relaterade typer.

Azure Service Fabric använde BinaryFormatter för serialiseringsfel. Från och med ServiceFabric v9.0 är datakontraktsbaserad serialisering för fjärrkommunikationsundantag tillgänglig som en opt-in-funktion. Vi rekommenderar att du väljer DataContract remoting-undantags serialisering genom att följa stegen i den här artikeln.

Stöd för BinaryFormatter-baserad serialisering av fjärrkommunikationsfel kommer att bli inaktuellt i framtiden.

Aktivera serialisering av datakontrakt för fjärrkommunikationsfel

Kommentar

Datakontraktsserialisering för fjärrkommunikationsfel är endast tillgängligt för fjärrkommunikation av V2/V2_1-tjänster.

Så här aktiverar du serialisering av datakontrakt för fjärrkommunikationsfel:

  1. Aktivera DataContract-undantagsserialisering på tjänstsidan med hjälp FabricTransportRemotingListenerSettings.ExceptionSerializationTechnique av när du skapar fjärrkommunikationslyssnaren.

    • Tillståndslös tjänst

      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
      Om du vill aktivera DataContract-undantagsserialisering för aktörstjänsten åsidosätter CreateServiceReplicaListeners() du genom att ActorServiceutöka .

      protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
      {
          return new List<ServiceReplicaListener>
          {
              new ServiceReplicaListener(_ =>
              {
                  return new FabricTransportActorServiceRemotingListener(
                      this,
                      new FabricTransportRemotingListenerSettings
                      {
                          ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default,
                      });
              },
              "MyActorServiceEndpointV2")
          };
      }
      

    Om det ursprungliga undantaget har flera nivåer av inre undantag kan du styra antalet nivåer av inre undantag som ska serialiseras genom att ange FabricTransportRemotingListenerSettings.RemotingExceptionDepth.

  2. Aktivera undantagsserier för DataContract-fjärrkommunikation på klienten med hjälp FabricTransportRemotingSettings.ExceptionDeserializationTechnique av när du skapar klientfabriken.

    • ServiceProxyFactory skapas

      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. DataContract remoting exception serialization konverterar ett undantag till dataöverföringsobjektet (DTO) på tjänstsidan. DTO:et konverteras tillbaka till ett undantag på klientsidan. Användarna måste registrera sig ExceptionConvertor för att konvertera önskade undantag till DTO-objekt och vice versa.

    Ramverket implementerar konverterare för följande lista över undantag. Om användartjänstkoden är beroende av undantag utanför följande lista för återförsöksimplementering och undantagshantering måste användarna implementera och registrera konverterare för sådana undantag.

    • Alla Service Fabric-undantag som härletts från System.Fabric.FabricException
    • SystemExceptions härledda från 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

Exempelimplementering av en konverterare på tjänstsidan för ett anpassat undantag

Följande exempel är referensimplementering IExceptionConvertortjänst- och klientsidan för en välkänd undantagstyp, 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 implementering på tjänstsidan :

    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;
        }
    }
    

Det faktiska undantaget som observerades under körningen av fjärrkommunikationsanropet skickas som indata till TryConvertToServiceException. Om undantagstypen är välkänd bör du konvertera det ursprungliga undantaget till ServiceException och returnera det som en out-parameterTryConvertToServiceException. Ett sant värde ska returneras om den ursprungliga undantagstypen är välkänd och det ursprungliga undantaget har konverterats till ServiceException. Annars är värdet falskt.

En lista över inre undantag på den aktuella nivån ska returneras av GetInnerExceptions().

  • IExceptionConvertor implementering på klientsidan :

    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 skickas som en parameter till TryConvertFromServiceException tillsammans med konverterad innerException[s]. Om den faktiska undantagstypen , ServiceException.ActualExceptionTypeär känd, bör konverteraren skapa ett faktiskt undantagsobjekt från ServiceException och innerException[s].

  • IExceptionConvertor registrering på tjänstsidan :

    Om du vill registrera konverterare CreateServiceInstanceListeners måste åsidosättas och listan över IExceptionConvertor klasser måste skickas när du skapar instansen RemotingListener .

    • Tillståndslös tjänst

      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 registrering på klientsidan :

    Om du vill registrera konverterare måste listan över IExceptionConvertor klasser skickas när du skapar instansen ClientFactory .

    • ServiceProxyFactory skapas

      var serviceProxyFactory = new ServiceProxyFactory(
      (callbackClient) =>
      {
         return new FabricTransportServiceRemotingClientFactory(
             new FabricTransportRemotingSettings
             {
                 ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default,
             },
             callbackClient,
             exceptionConvertors: new[]
             {
                 new CustomConvertorClient(),
             });
      });
      
    • ActorProxyFactory skapas

      var actorProxyFactory = new ActorProxyFactory(
      (callbackClient) =>
      {
          return new FabricTransportActorRemotingClientFactory(
              new FabricTransportRemotingSettings
              {
                  ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default,
              },
              callbackClient,
              exceptionConvertors: new[]
              {
                  new CustomConvertorClient(),
              });
      });
      

Kommentar

Om ramverket hittar konverteraren för undantaget omsluts det konverterade undantaget (faktiskt) inuti AggregateException och genereras vid fjärrkommunikations-API:et (proxy). Om ramverket inte hittar konverteraren ServiceExceptionomsluts , som innehåller all information om det faktiska undantaget, inuti AggregateException och genereras.

Uppgradera en befintlig tjänst för att aktivera serialisering av datakontrakt för fjärrkommunikationsfel

Befintliga tjänster måste följa följande ordning (tjänsten först) för att uppgradera. Om du inte följer den här ordningen kan det leda till att logiken och undantagshanteringen fungerar felaktigt.

  1. Implementera klasserna på tjänstsidan ExceptionConvertor för önskade undantag, om det finns några. Uppdatera registreringslogik för fjärrkommunikationslyssnare med ExceptionSerializationTechnique och listan över IExceptionConvertorklasser. Uppgradera den befintliga tjänsten för att tillämpa undantags serialiseringsändringarna.

  2. Implementera klasserna på klientsidan ExceptionConvertor för önskade undantag, om några. Uppdatera logiken för att skapa ProxyFactory med ExceptionSerializationTechnique och listan över IExceptionConvertor klasser. Uppgradera den befintliga klienten för att tillämpa undantags serialiseringsändringarna.

Nästa steg