Dela via


Testbarhetsscenarier

Stora distribuerade system som molninfrastrukturer är i sig otillförlitliga. Azure Service Fabric ger utvecklare möjlighet att skriva tjänster som kan köras ovanpå otillförlitliga infrastrukturer. För att kunna skriva högkvalitativa tjänster måste utvecklare kunna inducera en sådan otillförlitlig infrastruktur för att testa stabiliteten i sina tjänster.

Felanalystjänsten ger utvecklare möjlighet att inducera felåtgärder för att testa tjänster i närvaro av fel. Men riktade simulerade fel tar dig bara så långt. Om du vill fortsätta testningen kan du använda testscenarierna i Service Fabric: ett kaostest och ett redundanstest. Dessa scenarier simulerar kontinuerliga interfolierade fel, både graciösa och ospårbara, i hela klustret under längre tidsperioder. När ett test har konfigurerats med hastighet och typ av fel kan det startas via C#-API:er eller PowerShell för att generera fel i klustret och din tjänst.

Varning

ChaosTestScenario ersätts av ett mer motståndskraftigt, tjänstbaserat kaos. Mer information finns i den nya artikeln Kontrollerat kaos .

Kaostest

Kaosscenariot genererar fel i hela Service Fabric-klustret. Scenariot komprimerar fel som vanligtvis ses i månader eller år till några timmar. Kombinationen av interfolierade fel med den höga felfrekvensen hittar hörnfall som annars missas. Detta leder till en betydande förbättring av tjänstens kodkvalitet.

Fel simulerade i kaostestet

  • Starta om en nod
  • Starta om ett distribuerat kodpaket
  • Ta bort en replik
  • Starta om en replik
  • Flytta en primär replik (valfritt)
  • Flytta en sekundär replik (valfritt)

Kaostestet kör flera iterationer av fel och klustervalidering under den angivna tidsperioden. Den tid som används för att klustret ska stabiliseras och verifieringen ska lyckas kan också konfigureras. Scenariot misslyckas när du stöter på ett enda fel i klustervalidering.

Anta till exempel att en testuppsättning körs i en timme med högst tre samtidiga fel. Testet inducerar tre fel och validerar sedan klustrets hälsa. Testet itererar genom föregående steg tills klustret blir felfritt eller en timme passerar. Om klustret blir felfritt i en iteration, dvs. det inte stabiliseras inom en konfigurerad tid, misslyckas testet med ett undantag. Det här undantaget anger att något har gått fel och behöver undersökas ytterligare.

I sin nuvarande form inducerar felgenereringsmotorn i kaostestet endast säkra fel. Det innebär att i avsaknad av externa fel uppstår aldrig ett kvorum eller dataförlust.

Viktiga konfigurationsalternativ

  • TimeToRun: Total tid som testet körs innan det slutförs med framgång. Testet kan slutföras tidigare i stället för ett valideringsfel.
  • MaxClusterStabilizationTimeout: Maximal tid att vänta tills klustret blir felfritt innan testet misslyckas. De kontroller som utförs är om klusterhälsan är OK, tjänstens hälsa är OK, målreplikuppsättningens storlek uppnås för tjänstpartitionen och inga InBuild-repliker finns.
  • MaxConcurrentFaults: Maximalt antal samtidiga fel som induceras i varje iteration. Ju högre tal, desto aggressivare blir testet, vilket resulterar i mer komplexa redundans och övergångskombinationer. Testet garanterar att det i avsaknad av externa fel inte blir kvorum eller dataförlust, oavsett hur hög den här konfigurationen är.
  • EnableMoveReplicaFaults: Aktiverar eller inaktiverar de fel som orsakar flytten av de primära eller sekundära replikerna. Dessa fel är inaktiverade som standard.
  • WaitTimeBetweenIterations: Hur lång tid det tar att vänta mellan iterationer, dvs. efter en omgång fel och motsvarande validering.

Så här kör du kaostestet

C#-exempel

using System;
using System.Fabric;
using System.Fabric.Testability.Scenario;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    public static int Main(string[] args)
    {
        string clusterConnection = "localhost:19000";

        Console.WriteLine("Starting Chaos Test Scenario...");
        try
        {
            RunChaosTestScenarioAsync(clusterConnection).Wait();
        }
        catch (AggregateException ae)
        {
            Console.WriteLine("Chaos Test Scenario did not complete: ");
            foreach (Exception ex in ae.InnerExceptions)
            {
                if (ex is FabricException)
                {
                    Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
                }
            }
            return -1;
        }

        Console.WriteLine("Chaos Test Scenario completed.");
        return 0;
    }

    static async Task RunChaosTestScenarioAsync(string clusterConnection)
    {
        TimeSpan maxClusterStabilizationTimeout = TimeSpan.FromSeconds(180);
        uint maxConcurrentFaults = 3;
        bool enableMoveReplicaFaults = true;

        // Create FabricClient with connection and security information here.
        FabricClient fabricClient = new FabricClient(clusterConnection);

        // The chaos test scenario should run at least 60 minutes or until it fails.
        TimeSpan timeToRun = TimeSpan.FromMinutes(60);
        ChaosTestScenarioParameters scenarioParameters = new ChaosTestScenarioParameters(
          maxClusterStabilizationTimeout,
          maxConcurrentFaults,
          enableMoveReplicaFaults,
          timeToRun);

        // Other related parameters:
        // Pause between two iterations for a random duration bound by this value.
        // scenarioParameters.WaitTimeBetweenIterations = TimeSpan.FromSeconds(30);
        // Pause between concurrent actions for a random duration bound by this value.
        // scenarioParameters.WaitTimeBetweenFaults = TimeSpan.FromSeconds(10);

        // Create the scenario class and execute it asynchronously.
        ChaosTestScenario chaosScenario = new ChaosTestScenario(fabricClient, scenarioParameters);

        try
        {
            await chaosScenario.ExecuteAsync(CancellationToken.None);
        }
        catch (AggregateException ae)
        {
            throw ae.InnerException;
        }
    }
}

PowerShell

Service Fabric PowerShell-modulen innehåller två sätt att starta ett kaosscenario. Invoke-ServiceFabricChaosTestScenario är klientbaserad och om klientdatorn stängs av halvvägs genom testet introduceras inga ytterligare fel. Alternativt finns det en uppsättning kommandon som är avsedda att hålla testet igång om datorn stängs av. Start-ServiceFabricChaos använder en tillståndskänslig och tillförlitlig systemtjänst med namnet FaultAnalysisService, vilket säkerställer att fel förblir introducerade tills TimeToRun är igång. Stop-ServiceFabricChaos kan användas för att stoppa scenariot manuellt och Get-ServiceFabricChaosReport hämta en rapport. Mer information finns i Azure Service Fabric PowerShell-referensen och Inducera kontrollerat kaos i Service Fabric-kluster.

$connection = "localhost:19000"
$timeToRun = 60
$maxStabilizationTimeSecs = 180
$concurrentFaults = 3
$waitTimeBetweenIterationsSec = 60

Connect-ServiceFabricCluster $connection

Invoke-ServiceFabricChaosTestScenario -TimeToRunMinute $timeToRun -MaxClusterStabilizationTimeoutSec $maxStabilizationTimeSecs -MaxConcurrentFaults $concurrentFaults -EnableMoveReplicaFaults -WaitTimeBetweenIterationsSec $waitTimeBetweenIterationsSec

Redundanstest

Redundanstestscenariot är en version av scenariot med kaostestet som riktar sig mot en specifik tjänstpartition. Den testar effekten av redundansväxling på en specifik tjänstpartition samtidigt som de andra tjänsterna inte påverkas. När den har konfigurerats med målpartitionsinformationen och andra parametrar körs den som ett verktyg på klientsidan som använder antingen C#-API:er eller PowerShell för att generera fel för en tjänstpartition. Scenariot itererar genom en sekvens med simulerade fel och tjänstvalidering medan din affärslogik körs på sidan för att tillhandahålla en arbetsbelastning. Ett fel i tjänstverifieringen indikerar ett problem som behöver undersökas ytterligare.

Fel simulerade i redundanstestet

  • Starta om ett distribuerat kodpaket där partitionen finns
  • Ta bort en primär/sekundär replik eller tillståndslös instans
  • Starta om en primär sekundär replik (om en beständiga tjänst)
  • Flytta en primär replik
  • Flytta en sekundär replik
  • Starta om partitionen

Redundanstestet inducerar ett valt fel och kör sedan validering på tjänsten för att säkerställa dess stabilitet. Redundanstestet inducerar bara ett fel i taget, i motsats till eventuella flera fel i kaostestet. Om tjänstpartitionen inte stabiliseras inom den konfigurerade tidsgränsen efter varje fel misslyckas testet. Testet inducerar endast säkra fel. Det innebär att om det inte uppstår externa fel uppstår inte ett kvorum eller dataförlust.

Viktiga konfigurationsalternativ

  • PartitionSelector: Selector-objekt som anger den partition som måste riktas.
  • TimeToRun: Total tid som testet körs innan det slutförs.
  • MaxServiceStabilizationTimeout: Maximal tid att vänta tills klustret blir felfritt innan testet misslyckas. Kontrollerna som utförs är om tjänstens hälsotillstånd är OK, målreplikuppsättningens storlek uppnås för alla partitioner och inga InBuild-repliker finns.
  • WaitTimeBetweenFaults: Tid att vänta mellan varje fel- och valideringscykel.

Så här kör du redundanstestet

C#

using System;
using System.Fabric;
using System.Fabric.Testability.Scenario;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    public static int Main(string[] args)
    {
        string clusterConnection = "localhost:19000";
        Uri serviceName = new Uri("fabric:/samples/PersistentToDoListApp/PersistentToDoListService");

        Console.WriteLine("Starting Chaos Test Scenario...");
        try
        {
            RunFailoverTestScenarioAsync(clusterConnection, serviceName).Wait();
        }
        catch (AggregateException ae)
        {
            Console.WriteLine("Chaos Test Scenario did not complete: ");
            foreach (Exception ex in ae.InnerExceptions)
            {
                if (ex is FabricException)
                {
                    Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
                }
            }
            return -1;
        }

        Console.WriteLine("Chaos Test Scenario completed.");
        return 0;
    }

    static async Task RunFailoverTestScenarioAsync(string clusterConnection, Uri serviceName)
    {
        TimeSpan maxServiceStabilizationTimeout = TimeSpan.FromSeconds(180);
        PartitionSelector randomPartitionSelector = PartitionSelector.RandomOf(serviceName);

        // Create FabricClient with connection and security information here.
        FabricClient fabricClient = new FabricClient(clusterConnection);

        // The chaos test scenario should run at least 60 minutes or until it fails.
        TimeSpan timeToRun = TimeSpan.FromMinutes(60);
        FailoverTestScenarioParameters scenarioParameters = new FailoverTestScenarioParameters(
          randomPartitionSelector,
          timeToRun,
          maxServiceStabilizationTimeout);

        // Other related parameters:
        // Pause between two iterations for a random duration bound by this value.
        // scenarioParameters.WaitTimeBetweenIterations = TimeSpan.FromSeconds(30);
        // Pause between concurrent actions for a random duration bound by this value.
        // scenarioParameters.WaitTimeBetweenFaults = TimeSpan.FromSeconds(10);

        // Create the scenario class and execute it asynchronously.
        FailoverTestScenario failoverScenario = new FailoverTestScenario(fabricClient, scenarioParameters);

        try
        {
            await failoverScenario.ExecuteAsync(CancellationToken.None);
        }
        catch (AggregateException ae)
        {
            throw ae.InnerException;
        }
    }
}

PowerShell

$connection = "localhost:19000"
$timeToRun = 60
$maxStabilizationTimeSecs = 180
$waitTimeBetweenFaultsSec = 10
$serviceName = "fabric:/SampleApp/SampleService"

Connect-ServiceFabricCluster $connection

Invoke-ServiceFabricFailoverTestScenario -TimeToRunMinute $timeToRun -MaxServiceStabilizationTimeoutSec $maxStabilizationTimeSecs -WaitTimeBetweenFaultsSec $waitTimeBetweenFaultsSec -ServiceName $serviceName -PartitionKindSingleton