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


Tesztelhetőségi forgatókönyvek

A nagy elosztott rendszerek, például a felhőinfrastruktúra eleve megbízhatatlanok. Az Azure Service Fabric lehetővé teszi a fejlesztők számára, hogy megbízhatatlan infrastruktúrákon futtassanak szolgáltatásokat. A kiváló minőségű szolgáltatások írásához a fejlesztőknek képesnek kell lenniük arra, hogy megbízhatatlan infrastruktúrát indukáljanak a szolgáltatásaik stabilitásának teszteléséhez.

A Hibaelemzési szolgáltatás lehetővé teszi a fejlesztők számára, hogy hibaműveleteket indukáljanak a szolgáltatások meghibásodások jelenlétében történő teszteléséhez. A célzott szimulált hibák azonban csak eddig kapják meg. A tesztelés további elvégzéséhez használhatja a Service Fabric tesztforgatókönyveit: egy káosztesztet és egy feladatátvételi tesztet. Ezek a forgatókönyvek a fürtben hosszú időn keresztül folyamatos, kecses és nem gyalázatos hibákat szimulálnak. Ha egy teszt konfigurálva van a hibák sebességével és típusával, c# API-kkal vagy PowerShell-lel is elindítható, hogy hibákat generáljon a fürtben és a szolgáltatásban.

Figyelmeztetés

A ChaosTestScenario helyett egy rugalmasabb, szolgáltatásalapú Chaos áll. További részletekért tekintse meg a Szabályozott káosz című új cikket.

Káoszteszt

A káoszos forgatókönyv hibákat okoz a teljes Service Fabric-fürtben. A forgatókönyv néhány órára tömöríti a hónapokban vagy években általában látott hibákat. Az interleaved hibák és a magas hibaarány kombinációja megkeresi az egyébként kihagyott sarokeseteket. Ez a szolgáltatás kódminőségének jelentős javulásához vezet.

A káosztesztben szimulált hibák

  • Csomópont újraindítása
  • Üzembe helyezett kódcsomag újraindítása
  • Replika eltávolítása
  • Replika újraindítása
  • Elsődleges replika áthelyezése (nem kötelező)
  • Másodlagos replika áthelyezése (nem kötelező)

A káoszteszt több iterációt futtat a hibákból és a fürtérvényesítésből a megadott időtartamra. A fürt stabilizálásához és a sikeres ellenőrzéshez szükséges idő is konfigurálható. A forgatókönyv akkor meghiúsul, ha egyetlen hibát talál a fürtérvényesítés során.

Tegyük fel például, hogy egy tesztkészlet egy órán keresztül fut, legfeljebb három egyidejű hibával. A teszt három hibát okoz, majd ellenőrzi a fürt állapotát. A teszt végighalad az előző lépésen, amíg a fürt állapota nem lesz kifogástalan, vagy egy óra telik el. Ha a fürt bármilyen iterációban nem megfelelő állapotúvá válik, azaz nem stabilizálódik egy konfigurált időn belül, a teszt kivétellel meghiúsul. Ez a kivétel azt jelzi, hogy valami elromlott, és további vizsgálatot igényel.

Jelenlegi formájában a káoszteszt hibageneráló motorja csak a biztonságos hibákat idézi elő. Ez azt jelenti, hogy külső hibák hiányában a kvórum vagy az adatvesztés soha nem fordul elő.

Fontos konfigurációs beállítások

  • TimeToRun: A teszt sikeres befejezése előtt lefutott teljes idő. A teszt egy érvényesítési hiba helyett hamarabb befejeződhet.
  • MaxClusterStabilizationTimeout: A fürt kifogástalan állapotának eléréséhez szükséges maximális idő a teszt sikertelensége előtt. Az elvégzett ellenőrzések azt jelzik, hogy a fürt állapota rendben van-e, a szolgáltatás állapota rendben van-e, a célreplikakészlet mérete elérhető-e a szolgáltatáspartícióhoz, és nem léteznek InBuild replikák.
  • MaxConcurrentFaults: Az egyes iterációkban indukált egyidejű hibák maximális száma. Minél nagyobb a szám, annál agresszívabb a teszt, így összetettebb feladatátvételeket és áttűnési kombinációkat eredményez. A teszt garantálja, hogy külső hibák nélkül nem lesz kvórum vagy adatvesztés, függetlenül attól, hogy milyen magas ez a konfiguráció.
  • EnableMoveReplicaFaults: Engedélyezi vagy letiltja az elsődleges vagy másodlagos replikák áthelyezését okozó hibákat. Ezek a hibák alapértelmezés szerint le vannak tiltva.
  • WaitTimeBetweenIterations: Az iterációk közötti várakozási idő, azaz a hibák kerekítése és a megfelelő ellenőrzés után.

A káoszteszt futtatása

C#-minta

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

A Service Fabric PowerShell-modul két módszert tartalmaz a káoszos forgatókönyvek elindítására. Invoke-ServiceFabricChaosTestScenario ügyfélalapú, és ha az ügyfélszámítógép a teszt közben félúton le van állítva, további hibák nem lépnek fel. Másik lehetőségként egy parancskészlet is létezik, amely a teszt futtatását a gép leállítása esetén kívánja tartani. Start-ServiceFabricChaos a FaultAnalysisService nevű állapotalapú és megbízható rendszerszolgáltatást használja, biztosítva, hogy a hibák a TimeToRun üzembe helyezéséig megmaradnak. Stop-ServiceFabricChaos segítségével manuálisan állíthatja le a forgatókönyvet, és Get-ServiceFabricChaosReport beolvas egy jelentést. További információkért tekintse meg az Azure Service Fabric PowerShell-referenciát és az irányított káosz indukálását a Service Fabric-fürtökben.

$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

Feladatátvételi teszt

A feladatátvételi tesztforgatókönyv egy olyan káosztesztelési forgatókönyv verziója, amely egy adott szolgáltatáspartíciót céloz meg. Teszteli a feladatátvétel hatását egy adott szolgáltatáspartícióra, miközben a többi szolgáltatást nem érinti. Miután konfigurálta a célpartíciós adatokkal és más paraméterekkel, ügyféloldali eszközként fut, amely C# API-kat vagy PowerShellt használ a szolgáltatáspartíciók hibáinak létrehozásához. A forgatókönyv szimulált hibák és szolgáltatásérvényesítés sorozatán halad végig, miközben az üzleti logika az oldalon fut egy számítási feladat biztosításához. A szolgáltatásérvényesítési hiba azt a problémát jelzi, amely további vizsgálatot igényel.

A feladatátvételi teszt során szimulált hibák

  • Indítsa újra az üzembe helyezett kódcsomagot, amely a partíciót üzemelteti
  • Elsődleges/másodlagos replika vagy állapot nélküli példány eltávolítása
  • Elsődleges másodlagos replika újraindítása (ha egy megmaradó szolgáltatás)
  • Elsődleges replika áthelyezése
  • Másodlagos replika áthelyezése
  • Indítsa újra a partíciót

A feladatátvételi teszt egy kiválasztott hibát indukál, majd érvényesítést futtat a szolgáltatáson a stabilitás biztosítása érdekében. A feladatátvételi teszt egyszerre csak egy hibát idéz elő, szemben a káoszteszt lehetséges többszörös hibáival. Ha a szolgáltatáspartíció nem stabilizálódik a konfigurált időtúllépésen belül az egyes hibák után, a teszt sikertelen lesz. A teszt csak biztonságos hibákat okoz. Ez azt jelenti, hogy külső hibák hiányában nem lesz kvórum vagy adatvesztés.

Fontos konfigurációs beállítások

  • PartitionSelector: A megcélzandó partíciót meghatározó választóobjektum.
  • TimeToRun: A teszt futtatásának teljes időtartama a befejezés előtt.
  • MaxServiceStabilizationTimeout: A fürt kifogástalan állapotba kerülésének maximális időtartama a teszt sikertelensége előtt. Az elvégzett ellenőrzések azt jelzik, hogy a szolgáltatás állapota rendben van-e, a célreplikakészlet mérete az összes partícióhoz elérhető-e, és nem léteznek InBuild replikák.
  • WaitTimeBetweenFaults: Az összes hiba és ellenőrzési ciklus közötti várakozási idő.

A feladatátvételi teszt futtatása

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