Tindakan uji coba

Untuk mensimulasikan infrastruktur yang tidak dapat diandalkan, Azure Service Fabric memberi Anda, pengembang, cara untuk mensimulasikan berbagai kegagalan pada dunia nyata dan transisi status. Ini diekspos sebagai tindakan uji coba. Tindakan tersebut merupakan API tingkat rendah yang menyebabkan injeksi kesalahan, transisi status, atau validasi tertentu. Dengan menggabungkan tindakan ini, Anda dapat menulis skenario pengujian komprehensif untuk layanan Anda.

Service Fabric menyediakan beberapa skenario pengujian umum yang terdiri dari tindakan-tindakan ini. Kami sangat menyarankan Anda menggunakan skenario bawaan ini, yang dipilih dengan cermat untuk menguji transisi status umum dan kasus kegagalan. Namun, tindakan dapat digunakan untuk membuat skenario pengujian kustom ketika Anda ingin menambahkan cakupan skenario yang belum dicakup oleh skenario bawaan atau yang disesuaikan secara kustom untuk aplikasi Anda.

Implementasi C# dari tindakan tersebut ditemukan dalam perakitan System.Fabric.dll. Modul System Fabric PowerShell ditemukan pada perakitan Microsoft.ServiceFabric.Powershell.dll. Sebagai bagian dari instalasi runtime, modul ServiceFabric PowerShell diinstal untuk memungkinkan kemudahan penggunaan.

Tindakan kesalahan berat vs. ringan

Tindakan uji coba diklasifikasikan ke dalam dua wadah utama:

  • Kesalahan berat: Kesalahan ini mensimulasikan kegagalan seperti restart komputer dan crash proses. Dalam kasus kegagalan seperti itu, konteks eksekusi proses berhenti tiba-tiba. Ini berarti tidak ada pembersihan status yang dapat berjalan sebelum aplikasi dimulai lagi.
  • Kesalahan ringan: Kesalahan ini mensimulasikan tindakan ringan seperti gerakan replika dan penurunan yang dipicu oleh keseimbangan beban. Dalam kasus seperti itu, layanan mendapatkan pemberitahuan tentang penutupan dan dapat membersihkan status sebelum keluar.

Untuk validasi kualitas yang lebih baik, jalankan layanan dan beban kerja bisnis sambil menginduksi berbagai kesalahan ringan dan berat. Kesalahan berat menjalankan skenario di mana proses layanan tiba-tiba keluar di tengah-tengah beberapa alur kerja. Ini menguji jalur pemulihan setelah replika layanan dipulihkan oleh Service Fabric. Ini akan membantu menguji konsistensi data dan apakah status layanan dipertahankan dengan benar setelah kegagalan. Serangkaian kegagalan lainnya (kegagalan ringan) menguji bahwa layanan bereaksi dengan benar terhadap replika yang dipindahkan oleh Service Fabric. Ini menguji penanganan pembatalan dalam metode RunAsync. Layanan perlu memeriksa token pembatalan yang ditetapkan, menyimpan status dengan benar, dan keluar dari metode RunAsync.

Daftar tindakan uji coba

Tindakan Deskripsi API Terkelola PowerShell cmdlet Kesalahan ringan/berat
Menghapus TestState Menghapus semua status pengujian dari kluster jika driver pengujian mati dengan buruk. CleanTestStateAsync Remove-ServiceFabricTestState Tidak berlaku
InvokeDataLoss Menginduksi kehilangan data ke dalam partisi layanan. InvokeDataLossAsync Invoke-ServiceFabricPartitionDataLoss Ringan
InvokeQuorumLoss Menempatkan partisi layanan berstatus yang diberikan ke dalam kehilangan kuorum. InvokeQuorumLossAsync Invoke-ServiceFabricQuorumLoss Ringan
MovePrimary Memindahkan replika utama yang ditentukan dari layanan berstatus ke node kluster yang ditentukan. MovePrimaryAsync Move-ServiceFabricPrimaryReplica Ringan
MoveSecondary Memindahkan replika sekunder terbaru dari layanan berstatus ke node kluster yang berbeda. MoveSecondaryAsync Move-ServiceFabricSecondaryReplica Ringan
MoveInstance Memindahkan instans saat ini dari layanan tanpa status ke node kluster yang berbeda. MoveInstanceAsync Move-ServiceFabricInstance Ringan
RemoveReplica Mensimulasikan kegagalan replika dengan menghapus replika dari kluster. Ini akan menutup replika dan akan mengubahnya menjadi peran 'None', menghapus semua statusnya dari kluster. RemoveReplicaAsync Remove-ServiceFabricReplica Ringan
RestartDeployedCodePackage Mensimulasikan kegagalan proses paket kode dengan memulai ulang paket kode yang disebarkan pada node dalam kluster. Ini membatalkan proses paket kode, yang akan memulai ulang semua replika layanan pengguna yang dihosting dalam proses tersebut. RestartDeployedCodePackageAsync Restart-ServiceFabricDeployedCodePackage Berat
RestartNode Mensimulasikan kegagalan node kluster Service Fabric dengan memulai ulang node. RestartNodeAsync Restart-ServiceFabricNode Berat
RestartPartition Mensimulasikan skenario blackout pusat data atau blackout kluster dengan memulai ulang beberapa atau semua replika partisi. RestartPartitionAsync Restart-ServiceFabricPartition Ringan
RestartReplica Mensimulasikan kegagalan replika dengan memulai ulang replika yang bertahan di dalam kluster, menutup replika lalu membukanya kembali. RestartReplicaAsync Restart-ServiceFabricReplica Ringan
StartNode Memulai node dalam kluster yang sudah dihentikan. StartNodeAsync Start-ServiceFabricNode Tidak berlaku
StopNode Mensimulasikan kegagalan node dengan menghentikan node dalam kluster. Node akan tetap turun sampai StartNode dipanggil. StopNodeAsync Stop-ServiceFabricNode Berat
ValidateApplication Memvalidasi ketersediaan dan kesehatan semua layanan Service Fabric dalam aplikasi, biasanya setelah menginduksi beberapa kesalahan ke dalam sistem. ValidateApplicationAsync Test-ServiceFabricApplication Tidak berlaku
ValidateService Memvalidasi ketersediaan dan kesehatan layanan Service Fabric, biasanya setelah menginduksi beberapa kesalahan ke dalam sistem. ValidateServiceAsync Test-ServiceFabricService Tidak berlaku

Menjalankan tindakan uji coba menggunakan PowerShell

Tutorial ini menunjukkan kepada Anda cara menjalankan tindakan uji coba dengan menggunakan PowerShell. Anda akan mempelajari cara menjalankan tindakan pengujian terhadap kluster lokal (satu kotak) atau kluster Azure. Microsoft.Fabric.Powershell.dll--modul Service Fabric PowerShell module--diinstal secara otomatis saat Anda menginstal Microsoft Service Fabric MSI. Modul dimuat secara otomatis saat Anda membuka prompt PowerShell.

Segmen tutorial:

Menjalankan tindakan terhadap kluster satu kotak

Untuk menjalankan tindakan uji terhadap kluster lokal, pertama-tama sambungkan ke kluster dan buka prompt PowerShell dalam mode administrator. Mari kita lihat tindakan Restart-ServiceFabricNode.

Restart-ServiceFabricNode -NodeName Node1 -CompletionMode DoNotVerify

Di sini tindakan Restart-ServiceFabricNode sedang dijalankan pada node bernama "Node1". Mode penyelesaian menentukan bahwa tidak boleh memverifikasi apakah tindakan memulai ulang node benar-benar berhasil. Menentukan mode penyelesaian sebagai "Verifikasi" akan menyebabkannya memverifikasi apakah tindakan mulai ulang benar-benar berhasil. Alih-alih secara langsung menentukan node berdasarkan namanya, Anda dapat menentukannya melalui kunci partisi dan jenis replika, sebagai berikut:

Restart-ServiceFabricNode -ReplicaKindPrimary  -PartitionKindNamed -PartitionKey Partition3 -CompletionMode Verify
$connection = "localhost:19000"
$nodeName = "Node1"

Connect-ServiceFabricCluster $connection
Restart-ServiceFabricNode -NodeName $nodeName -CompletionMode DoNotVerify

Restart-ServiceFabricNode harus digunakan untuk memulai ulang node Service Fabric dalam kluster. Ini akan menghentikan proses Fabric.exe, yang akan memulai ulang semua layanan sistem dan replika layanan pengguna yang dihosting pada node tersebut. Menggunakan API ini untuk menguji layanan Anda membantu menemukan bug di sepanjang jalur pemulihan failover. Ini membantu mensimulasikan kegagalan node dalam kluster.

Cuplikan layar berikut menunjukkan perintah uji coba Restart-ServiceFabricNode dalam tindakan.

Cuplikan layar menjalankan perintah Restart-ServiceFabricNode di PowerShell.

Output dari Get-ServiceFabricNode pertama (cmdlet dari modul Service Fabric PowerShell) menunjukkan bahwa kluster lokal memiliki lima node: Node.1 ke Node.5. Setelah tindakan uji coba (cmdlet) Restart-ServiceFabricNode dieksekusi pada node, bernama Node.4, kami melihat bahwa waktu aktif node telah diatur ulang.

Menjalankan tindakan terhadap kluster Azure

Menjalankan tindakan uji coba (dengan menggunakan PowerShell) terhadap kluster Azure mirip dengan menjalankan tindakan terhadap kluster lokal. Satu-satunya perbedaan adalah sebelum Anda dapat menjalankan tindakan, alih-alih menyambungkan ke kluster lokal, Anda harus terhubung ke kluster Azure terlebih dahulu.

Menjalankan tindakan uji coba menggunakan C#

Untuk menjalankan tindakan uji coba menggunakan C#, pertama-tama Anda perlu terhubung ke kluster dengan menggunakan FabricClient. Kemudian dapatkan parameter yang diperlukan untuk menjalankan tindakan. Parameter yang berbeda dapat digunakan untuk menjalankan tindakan yang sama. Melihat tindakan RestartServiceFabricNode, salah satu cara untuk menjalankannya adalah dengan menggunakan informasi node (nama node dan ID instans node) pada kluster.

RestartNodeAsync(nodeName, nodeInstanceId, completeMode, operationTimeout, CancellationToken.None)

Penjelasan parameter:

  • CompleteMode menentukan bahwa mode tidak boleh memverifikasi apakah tindakan memulai ulang benar-benar berhasil. Menentukan mode penyelesaian sebagai "Verifikasi" akan menyebabkannya memverifikasi apakah tindakan mulai ulang benar-benar berhasil.
  • OperationTimeout menetapkan jumlah waktu untuk operasi selesai sebelum pengecualian TimeoutException ditentukan.
  • CancellationToken memungkinkan panggilan tertunda untuk dibatalkan.

Alih-alih secara langsung menentukan node berdasarkan namanya, Anda dapat menentukannya melalui kunci partisi dan jenis replika.

Untuk informasi lebih lanjut, lihat PartitionSelector dan ReplicaSelector.

// Add a reference to System.Fabric.Testability.dll and System.Fabric.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Fabric.Testability;
using System.Fabric;
using System.Threading;
using System.Numerics;

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

        Console.WriteLine("Starting RestartNode test");
        try
        {
            //Restart the node by using ReplicaSelector
            RestartNodeAsync(clusterConnection, serviceName).Wait();

            //Another way to restart node is by using nodeName and nodeInstanceId
            RestartNodeAsync(clusterConnection, nodeName, nodeInstanceId).Wait();
        }
        catch (AggregateException exAgg)
        {
            Console.WriteLine("RestartNode did not complete: ");
            foreach (Exception ex in exAgg.InnerExceptions)
            {
                if (ex is FabricException)
                {
                    Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
                }
            }
            return -1;
        }

        Console.WriteLine("RestartNode completed.");
        return 0;
    }

    static async Task RestartNodeAsync(string clusterConnection, Uri serviceName)
    {
        PartitionSelector randomPartitionSelector = PartitionSelector.RandomOf(serviceName);
        ReplicaSelector primaryofReplicaSelector = ReplicaSelector.PrimaryOf(randomPartitionSelector);

        // Create FabricClient with connection and security information here
        FabricClient fabricclient = new FabricClient(clusterConnection);
        await fabricclient.FaultManager.RestartNodeAsync(primaryofReplicaSelector, CompletionMode.Verify);
    }

    static async Task RestartNodeAsync(string clusterConnection, string nodeName, BigInteger nodeInstanceId)
    {
        // Create FabricClient with connection and security information here
        FabricClient fabricclient = new FabricClient(clusterConnection);
        await fabricclient.FaultManager.RestartNodeAsync(nodeName, nodeInstanceId, CompletionMode.Verify);
    }
}

PartitionSelector and ReplicaSelector

PartitionSelector

PartitionSelector adalah pembantu yang terekspos dalam uji coba dan digunakan untuk memilih partisi tertentu tindakan uji coba apa dilakukan. Ini dapat digunakan untuk memilih partisi tertentu jika ID partisi diketahui sebelumnya. Atau, Anda dapat menyediakan kunci partisi dan operasi akan menyelesaikan ID partisi secara internal. Anda juga memiliki opsi untuk memilih partisi acak.

Untuk menggunakan pembantu ini, buat objek PartitionSelector dan pilih partisi menggunakan salah satu metode Pilih*. Kemudian lewati objek PartitionSelector ke API yang memerlukannya. Jika tidak ada opsi yang dipilih, maka secara default ke partisi acak.

Uri serviceName = new Uri("fabric:/samples/InMemoryToDoListApp/InMemoryToDoListService");
Guid partitionIdGuid = new Guid("8fb7ebcc-56ee-4862-9cc0-7c6421e68829");
string partitionName = "Partition1";
Int64 partitionKeyUniformInt64 = 1;

// Select a random partition
PartitionSelector randomPartitionSelector = PartitionSelector.RandomOf(serviceName);

// Select a partition based on ID
PartitionSelector partitionSelectorById = PartitionSelector.PartitionIdOf(serviceName, partitionIdGuid);

// Select a partition based on name
PartitionSelector namedPartitionSelector = PartitionSelector.PartitionKeyOf(serviceName, partitionName);

// Select a partition based on partition key
PartitionSelector uniformIntPartitionSelector = PartitionSelector.PartitionKeyOf(serviceName, partitionKeyUniformInt64);

ReplicaSelector

ReplicaSelector adalah pembantu yang terekspos dalam uji coba dan digunakan untuk membantu memilih replika terekspos tindakan uji coba apa pun dilakukan. Ini dapat digunakan untuk memilih replika tertentu jika ID replika diketahui sebelumnya. Selain itu, Anda memiliki opsi untuk memilih replika utama atau sekunder acak. ReplicaSelector berasal dari PartitionSelector, jadi Anda perlu memilih replika dan partisi tempat Anda ingin melakukan operasi uji coba.

Untuk menggunakan pembantu ini, buat objek ReplicaSelector dan atur cara Anda ingin memilih replika dan partisi. Kemudian Anda dapat meneruskannya ke API yang memerlukannya. Jika tidak ada opsi yang dipilih, maka akan secara default ke replika acak dan partisi acak.

Guid partitionIdGuid = new Guid("8fb7ebcc-56ee-4862-9cc0-7c6421e68829");
PartitionSelector partitionSelector = PartitionSelector.PartitionIdOf(serviceName, partitionIdGuid);
long replicaId = 130559876481875498;

// Select a random replica
ReplicaSelector randomReplicaSelector = ReplicaSelector.RandomOf(partitionSelector);

// Select the primary replica
ReplicaSelector primaryReplicaSelector = ReplicaSelector.PrimaryOf(partitionSelector);

// Select the replica by ID
ReplicaSelector replicaByIdSelector = ReplicaSelector.ReplicaIdOf(partitionSelector, replicaId);

// Select a random secondary replica
ReplicaSelector secondaryReplicaSelector = ReplicaSelector.RandomSecondaryOf(partitionSelector);

Langkah berikutnya