Skenario uji coba

Sistem terdistribusi besar seperti infrastruktur cloud pada dasarnya tidak dapat diandalkan. Azure Service Fabric memberi pengembang kemampuan untuk menulis layanan untuk berjalan di atas infrastruktur yang tidak dapat diandalkan. Untuk menulis layanan berkualitas tinggi, pengembang harus dapat menginduksi infrastruktur yang tidak dapat diandalkan tersebut untuk menguji stabilitas layanan mereka.

Fault Analysis Service memberi pengembang kemampuan untuk menginduksi tindakan fault untuk menguji layanan di hadapan kegagalan. Namun, fault simulasi yang ditargetkan akan membuat Anda hanya sejauh ini. Untuk mengambil pengujian lebih lanjut, Anda dapat menggunakan skenario pengujian di Service Fabric: uji chaos dan uji failover. Skenario ini mensimulasikan fault terus menerus dan saling berselang (baik ringan maupun berat) di seluruh kluster selama jangka waktu yang lama. Setelah pengujian dikonfigurasi dengan laju dan jenis fault, itu dapat dimulai melalui C# API atau PowerShell, untuk menghasilkan fault di kluster dan layanan Anda.

Peringatan

ChaosTestScenario digantikan oleh Chaos yang lebih tangguh dan berbasis layanan. Harap lihat artikel baru Controlled Chaos untuk detail lebih lanjut.

Uji chaos

Skenario chaos menghasilkan fault di seluruh kluster Service Fabric. Skenario mengompresi fault umumnya terlihat dalam bulan atau tahun hingga beberapa jam. Kombinasi fault yang disisipkan dengan tingkat fault tinggi menemukan kasus sudut yang mungkin terlewatkan. Ini menyebabkan peningkatan yang signifikan dalam kualitas kode layanan.

Fault yang disimulasikan dalam uji chaos

  • Merestart node
  • Merestart paket kode yang disebarkan
  • Menghapus replika
  • Merestart replika
  • Memindahkan replika utama (opsional)
  • Memindahkan replika sekunder (opsional)

Uji chaos menjalankan beberapa iterasi fault dan validasi kluster untuk periode waktu yang ditentukan. Waktu yang dihabiskan agar kluster stabil dan validasi berhasil juga dapat dikonfigurasi. Skenario gagal ketika Anda mengalami kegagalan tunggal dalam validasi kluster.

Misalnya, pertimbangkan set pengujian untuk berjalan selama satu jam dengan maksimum tiga fault bersamaan. Uji ini akan menginduksi tiga fault, dan kemudian memvalidasi kesehatan kluster. Uji akan mundur melalui langkah sebelumnya sampai kluster menjadi tidak sehat atau satu jam berlalu. Jika kluster menjadi tidak sehat dalam iterasi apa pun, yaitu tidak stabil dalam waktu yang dikonfigurasi, uji akan gagal dengan pengecualian. Pengecualian ini menunjukkan bahwa ada yang tidak beres dan perlu probe lebih lanjut.

Dalam bentuk saat ini, mesin penghasil fault dalam uji chaos hanya menginduksi safe fault. Ini berarti bahwa dengan tidak adanya fault eksternal, kuorum atau kehilangan data tidak akan pernah terjadi.

Opsi konfigurasi penting

  • TimeToRun: Total waktu uji akan berjalan sebelum selesai dengan sukses. Uji dapat selesai lebih awal sebagai pengganti kegagalan validasi.
  • MaxClusterStabilizationTimeout: Jumlah waktu maksimum untuk menunggu kluster menjadi sehat sebelum gagal uji. Pemeriksaan yang dilakukan adalah apakah kesehatan kluster OK, kesehatan layanan OK, ukuran set replika target dicapai untuk partisi layanan, dan tidak ada replika InBuild yang ada.
  • MaxConcurrentFaults: Jumlah maksimum fault serentak yang diinduksi di setiap iterasi. Semakin tinggi angkanya, semakin agresif uji, karenanya menghasilkan failover dan kombinasi transisi yang lebih kompleks. Uji ini menjamin bahwa dengan tidak adanya fault eksternal tidak akan ada kuorum atau kehilangan data, terlepas dari seberapa tinggi konfigurasi ini.
  • EnableMoveReplicaFaults: Mengaktifkan atau menonaktifkan fault yang menyebabkan pemindahan replika primer atau sekunder. Fault ini diaktifkan secara default.
  • WaitTimeBetweenIterations: Jumlah waktu untuk menunggu di antara iterasi, yaitu setelah putaran fault dan validasi yang sesuai.

Cara menjalankan uji chaos

Sampel 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";

        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

Modul Service Fabric Powershell mencakup dua cara untuk memulai skenario kekacauan. Invoke-ServiceFabricChaosTestScenario berbasis klien, dan jika komputer klien dimatikan di tengah uji, tidak ada fault lebih lanjut yang akan diperkenalkan. Atau, ada serangkaian perintah yang dimaksudkan untuk menjaga pengujian tetap berjalan jika terjadi pematian komputer. Start-ServiceFabricChaos menggunakan layanan sistem yang canggih dan andal yang disebut FaultAnalysisService, yang memastikan fault akan tetap diperkenalkan sampai TimeToRun habis. Stop-ServiceFabricChaos dapat digunakan untuk menghentikan skenario secara manual, dan Get-ServiceFabricChaosReport akan mendapatkan laporan. Untuk informasi selengkapnya, lihat referensi Azure Service Fabric Powershell dan Menginduksi kekacauan terkontrol di kluster Service Fabric.

$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

Uji failover

Skenario uji failover adalah versi skenario uji chaos yang menargetkan partisi layanan tertentu. Ini menguji efek failover pada partisi layanan tertentu sambil meninggalkan layanan lain yang tidak terpengaruh. Setelah dikonfigurasi dengan informasi partisi target dan parameter lainnya, ia berjalan sebagai alat sisi klien yang menggunakan C# API atau PowerShell untuk menghasilkan fault untuk partisi layanan. Skenario ini bermalas-bentuk melalui urutan fault simulasi dan validasi layanan saat logika bisnis Anda berjalan di samping untuk menyediakan beban kerja. Kegagalan dalam validasi layanan menunjukkan masalah yang perlu diselidiki lebih lanjut.

Fault yang disimulasikan dalam uji failover

  • Memulai ulang paket kode yang disebarkan di mana partisi dihosting
  • Menghapus replika utama/sekunder atau instans stateless
  • Memulai ulang replika sekunder utama (jika layanan bertahan)
  • Memindahkan replika utama
  • Memindahkan replika sekunder
  • Memulai ulang partisi

Uji failover menginduksi fault yang dipilih dan kemudian menjalankan validasi pada layanan untuk memastikan stabilitasnya. Uji failover hanya menginduksi satu fault pada satu waktu, dibandingkan dengan kemungkinan beberapa fault dalam uji chaos. Jika partisi layanan tidak stabil dalam batas waktu yang dikonfigurasi setelah setiap fault, pengujian gagal. Uji hanya menginduksi safe fault. Ini berarti bahwa dengan tidak adanya kegagalan eksternal, kuorum, atau kehilangan data tidak akan terjadi.

Opsi konfigurasi penting

  • PartitionSelector: Objek pemilih yang menentukan partisi yang perlu ditargetkan.
  • TimeToRun: Total waktu uji akan berjalan sebelum selesai.
  • MaxServiceStabilizationTimeout: Jumlah waktu maksimum untuk menunggu kluster menjadi sehat sebelum gagal uji. Pemeriksaan yang dilakukan adalah apakah kesehatan layanan OK, ukuran set replika target dicapai untuk semua partisi, dan tidak ada replika InBuild yang ada.
  • WaitTimeBetweenFaults: Jumlah waktu untuk menunggu antara setiap fault dan siklus validasi.

Cara menjalankan uji failover

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