Bagikan melalui


Keamanan utas dan manajemen masa pakai klien untuk objek Azure SDK

Artikel ini membantu Anda memahami masalah keamanan utas saat menggunakan Azure SDK. Ini juga membahas bagaimana desain SDK berdampak pada manajemen masa pakai klien. Anda akan mempelajari mengapa tidak perlu membuang objek klien Azure SDK.

Keamanan utas

Semua objek klien Azure SDK aman utas dan independen satu sama lain. Desain ini memastikan bahwa menggunakan kembali instans klien selalu aman, bahkan di seluruh utas. Misalnya, kode berikut meluncurkan beberapa tugas tetapi aman untuk utas:

var client = new SecretClient(
    new Uri("<secrets_endpoint>"), new DefaultAzureCredential());

foreach (var secretName in secretNames)
{
    // Using clients from parallel threads
    Task.Run(() => Console.WriteLine(client.GetSecret(secretName).Value));
}

Objek model yang digunakan oleh klien SDK, baik model input atau output, tidak aman secara default. Sebagian besar kasus penggunaan yang melibatkan objek model hanya menggunakan satu utas. Oleh karena itu, biaya penerapan sinkronisasi sebagai perilaku default terlalu tinggi untuk objek ini. Kode berikut mengilustrasikan bug di mana mengakses model dari beberapa utas dapat menyebabkan perilaku yang tidak terdefinisi:

KeyVaultSecret newSecret = client.SetSecret("secret", "value");

foreach (var tag in tags)
{
    // Don't use model type from parallel threads
    Task.Run(() => newSecret.Properties.Tags[tag] = CalculateTagValue(tag));
}

client.UpdateSecretProperties(newSecret.Properties);

Untuk mengakses model dari utas yang berbeda, Anda harus menerapkan kode sinkronisasi Anda sendiri. Misalnya:

KeyVaultSecret newSecret = client.SetSecret("secret", "value");

// Code omitted for brevity

foreach (var tag in tags)
{
    Task.Run(() =>
    {
        lock (newSecret)
        {
            newSecret.Properties.Tags[tag] = CalculateTagValue(tag);
        }
    );
}

client.UpdateSecretProperties(newSecret.Properties);

Masa pakai klien

Karena klien Azure SDK aman utas, tidak ada alasan untuk membuat beberapa objek klien SDK untuk sekumpulan parameter konstruktor tertentu. Perlakukan objek klien Azure SDK sebagai singleton setelah dibangun. Rekomendasi ini umumnya diimplementasikan dengan mendaftarkan objek klien Azure SDK sebagai singleton dalam kontainer Inversion of Control (IoC) aplikasi. Injeksi dependensi (DI) digunakan untuk mendapatkan referensi ke objek klien SDK. Contoh berikut menunjukkan pendaftaran objek klien singleton:

var builder = Host.CreateApplicationBuilder(args);

var endpoint = builder.Configuration["SecretsEndpoint"];
var blobServiceClient = new BlobServiceClient(
    new Uri(endpoint), new DefaultAzureCredential());

builder.Services.AddSingleton(blobServiceClient);

Untuk informasi selengkapnya tentang menerapkan DI dengan Azure SDK, lihat Injeksi dependensi dengan Azure SDK untuk .NET.

Atau, Anda dapat membuat instans klien SDK dan menyediakannya ke metode yang memerlukan klien. Intinya adalah untuk menghindari instansiasi yang tidak perlu dari objek klien SDK yang sama dengan parameter yang sama. Ini tidak perlu dan boros.

Klien tidak dapat dibuang

Dua pertanyaan terakhir yang sering muncul adalah:

  • Apakah saya perlu membuang objek klien Azure SDK saat saya selesai menggunakannya?
  • Mengapa objek klien Azure SDK berbasis HTTP tidak sekali pakai?

Secara internal, semua klien Azure SDK menggunakan satu instans bersama HttpClient . Klien tidak membuat sumber daya lain yang perlu dibebaskan secara aktif. Instans bersama HttpClient bertahan sepanjang seluruh masa pakai aplikasi.

// Both clients reuse the shared HttpClient and don't need to be disposed
var blobClient = new BlobClient(new Uri(sasUri));
var blobClient2 = new BlobClient(new Uri(sasUri2));

Dimungkinkan untuk menyediakan instans HttpClient kustom ke objek klien Azure SDK. Dalam hal ini, Anda menjadi bertanggung jawab untuk mengelola HttpClient masa pakai dan membuangnya dengan benar pada waktu yang tepat.

var httpClient = new HttpClient();

var clientOptions = new BlobClientOptions()
{
    Transport = new HttpClientTransport(httpClient)
};

// Both clients would use the HttpClient instance provided in clientOptions
var blobClient = new BlobClient(new Uri(sasUri), clientOptions);
var blobClient2 = new BlobClient(new Uri(sasUri2), clientOptions);

// Code omitted for brevity

// You're responsible for properly disposing httpClient some time later
httpClient.Dispose();

Panduan lebih lanjut untuk mengelola dan membuang instans HttpClient dengan benar dapat ditemukan dalam HttpClient dokumentasi.

Lihat juga