Pola Konsumen Bersaing

Azure Functions
Azure Service Bus

Memungkinkan beberapa konsumen untuk memproses pesan yang diterima di saluran pesan yang sama secara bersamaan. Dengan beberapa konsumen yang bersamaan, sistem dapat memproses beberapa pesan secara bersamaan untuk mengoptimalkan throughput, meningkatkan skalabilitas dan ketersediaan, serta menyeimbangkan beban kerja.

Konteks dan masalah

Aplikasi yang berjalan di cloud diharapkan dapat menangani permintaan dalam jumlah besar. Alih-alih memproses setiap permintaan secara sinkron, teknik yang biasa dipakai adalah aplikasi meneruskannya melalui sistem Olahpesan ke layanan lain (layanan konsumen) yang menanganinya secara asinkron. Strategi ini membantu memastikan bahwa logika bisnis dalam aplikasi tidak diblokir, selagi permintaan sedang diproses.

Jumlah permintaan dapat berbeda secara signifikan dari waktu ke waktu karena berbagai alasan. Peningkatan mendadak dalam aktivitas pengguna atau permintaan agregat yang berasal dari beberapa penyewa dapat menyebabkan beban kerja yang tidak terduga. Pada jam sibuk, sistem mungkin perlu memproses ratusan permintaan per detik, sementara di waktu lain jumlah permintaannya bisa sangat kecil. Selain itu, sifat pekerjaan yang dilakukan untuk menangani permintaan ini mungkin sangat bervariasi. Dengan menggunakan satu instans layanan konsumen, Anda dapat menyebabkan instans tersebut dibanjiri permintaan. Atau, sistem Olahpesan mungkin kelebihan beban karena masuknya pesan dalam jumlah besar yang berasal dari aplikasi. Untuk menangani beban kerja yang naik turun seperti ini, sistem dapat menjalankan beberapa instans layanan konsumen. Namun, konsumen-konsumen ini harus dikoordinasikan untuk memastikan bahwa setiap pesan hanya disampaikan kepada satu konsumen. Beban kerja juga perlu diseimbangkan ke seluruh konsumen untuk mencegah sebuah instans menjadi penyempitan.

Solusi

Gunakan antrean pesan untuk mengimplementasikan saluran komunikasi antara aplikasi dan instans layanan konsumen. Aplikasi memposting permintaan dalam bentuk pesan ke antrean, dan instans layanan konsumen menerima pesan dari antrean dan memprosesnya. Pendekatan ini memungkinkan kumpulan instans layanan konsumen yang sama untuk menangani pesan dari instans aplikasi mana pun. Gambar tersebut mengilustrasikan penggunaan antrean pesan untuk mendistribusikan pekerjaan kepada instans layanan.

Menggunakan antrean pesan untuk mendistribusikan pekerjaan ke instans layanan

Catatan

Meskipun ada beberapa konsumen pesan ini, ini tidak sama dengan pola Terbitkan Berlangganan (pub/sub). Dengan pendekatan Competing Consumers, setiap pesan diteruskan ke satu konsumen untuk diproses, sedangkan dengan pendekatan Pub/Sub, semua konsumen diteruskan setiap pesan.

Solusi ini memiliki beberapa manfaat sebagai berikut:

  • Solusi ini menyediakan sistem dengan beban merata yang dapat menangani berbagai variasi volume permintaan yang dikirim oleh instans aplikasi. Antrean bertindak sebagai buffer antara instans aplikasi dan instans layanan konsumen. Buffer ini dapat membantu meminimalkan dampak pada ketersediaan dan responsivitas, baik untuk aplikasi maupun instans layanan. Untuk informasi selengkapnya, lihat Pola Pemerataan Beban Berbasis Antrean. Menangani pesan yang memerlukan beberapa pemrosesan panjang tidak akan mencegah pesan lain ditangani secara bersamaan oleh instans lain layanan konsumen.

  • Solusi ini meningkatkan keandalan. Jika produsen berkomunikasi langsung dengan konsumen alih-alih menggunakan pola ini, tetapi tidak memantau konsumen, ada kemungkinan besar pesan akan hilang atau gagal diproses jika konsumen gagal. Dalam pola ini, pesan tidak dikirim ke instans layanan tertentu. Instans layanan yang gagal tidak akan memblokir produser, dan pesan dapat diproses oleh instans layanan mana pun yang berfungsi.

  • Solusi ini tidak memerlukan koordinasi yang kompleks antar-konsumen, atau antara produsen dan instans konsumen. Antrean pesan memastikan bahwa setiap pesan terkirim setidaknya sekali.

  • Solusi ini dapat diskalakan. Saat Anda menerapkan penskalaan otomatis, sistem dapat secara dinamis meningkatkan atau mengurangi jumlah instans layanan konsumen saat volume pesan berfluktuasi.

  • Solusi ini dapat meningkatkan ketahanan jika antrean pesan menyediakan operasi baca transaksional. Jika instans layanan konsumen membaca dan memproses pesan sebagai bagian dari operasi transaksional, dan instans layanan konsumen gagal beroperasi, pola ini dapat memastikan bahwa pesan akan dikembalikan ke antrean untuk diambil dan ditangani oleh instans layanan konsumen lain. Untuk mengurangi risiko pesan yang terus gagal, kami sarankan Anda menggunakan antrean surat mati.

Masalah dan pertimbangan

Pertimbangkan poin-poin berikut saat memutuskan cara menerapkan pola ini:

  • Pengurutan pesan. Urutan instans layanan konsumen menerima pesan tidak dijamin, dan tidak selalu mencerminkan urutan pembuatan pesan. Rancang sistem untuk memastikan bahwa pemrosesan pesan bersifat idempoten karena ini akan membantu menghilangkan dependensi pada urutan penanganan pesan. Untuk informasi selengkapnya, lihat Pola Idempotensi di blog milik Jonathon Oliver.

    Antrean Microsoft Azure Service Bus dapat mengimplementasikan jaminan urutan pesan masuk pertama juga akan keluar pertama menggunakan sesi pesan. Untuk informasi selengkapnya, lihat Pola Olahpesan Menggunakan Sesi.

  • Merancang layanan untuk ketahanan. Jika sistem dirancang untuk mendeteksi dan memulai ulang instans layanan yang gagal, mungkin perlu untuk mengimplementasikan pemrosesan yang dilakukan oleh instans layanan sebagai operasi idempoten guna meminimalkan efek dari satu pesan yang diambil dan diproses lebih dari sekali.

  • Mendeteksi pesan racun. Pesan yang salah format, atau tugas yang memerlukan akses ke sumber daya yang tidak tersedia, dapat menyebabkan instans layanan gagal beroperasi. Sistem harus mencegah agar pesan tersebut tidak dikembalikan ke antrean, dan sebagai gantinya menangkap dan menyimpan detail pesan ini di tempat lain sehingga dapat dianalisis jika perlu.

  • Menangani hasil. Instans layanan yang menangani pesan sepenuhnya dipisahkan dari logika aplikasi yang menghasilkan pesan, dan mungkin tidak dapat berkomunikasi secara langsung. Jika instans layanan memberikan hasil yang harus diteruskan kembali ke logika aplikasi, informasi ini harus disimpan di lokasi yang dapat diakses oleh keduanya. Untuk mencegah logika aplikasi mengambil data yang tidak lengkap, sistem harus memberikan indikasi ketika pemrosesan sudah selesai.

    Jika Anda menggunakan Azure, proses pekerja dapat meneruskan hasil kembali ke logika aplikasi dengan menggunakan antrean balasan pesan khusus. Logika aplikasi harus dapat menyambungkan hasil ini dengan pesan asli. Skenario ini dijelaskan lebih mendetail di Primer Olahpesan Asinkron.

  • Menskalakan sistem Olahpesan. Dalam solusi berskala besar, antrean pesan tunggal dapat kewalahan oleh banyaknya jumlah pesan sehingga menjadi hambatan dalam sistem. Dalam situasi ini, pertimbangkan untuk mempartisi sistem Olahpesan untuk mengirim pesan dari suatu produsen ke antrean tertentu, atau menggunakan penyeimbangan beban guna mendistribusikan pesan di beberapa antrean pesan.

  • Memastikan keandalan sistem Olahpesan. Sistem Olahpesan yang andal diperlukan untuk menjamin bahwa setelah aplikasi menambahkan pesan ke dalam antrean, pesan tersebut tidak akan hilang. Sistem ini sangat penting untuk memastikan bahwa semua pesan dikirimkan setidaknya sekali.

Kapan menggunakan pola ini

Gunakan pola ini ketika:

  • Beban kerja untuk sebuah aplikasi dibagi menjadi tugas-tugas yang dapat berjalan secara asinkron.
  • Tugas bersifat independen dan dapat dijalankan secara paralel.
  • Volume pekerjaan sangat bervariasi, sehingga membutuhkan solusi yang dapat diskalakan.
  • Solusinya harus menyediakan ketersediaan tinggi, dan harus tangguh jika pemrosesan tugas gagal.

Pola ini mungkin tidak berguna jika:

  • Sulit untuk memisahkan beban kerja aplikasi menjadi tugas-tugas yang berbeda, atau ada tingkat dependensi yang tinggi antar-tugas.
  • Tugas harus dilakukan secara sinkron, dan logika aplikasi harus menunggu tugas selesai sebelum melanjutkan.
  • Tugas harus dilakukan dalam urutan yang spesifik.

Beberapa sistem Olahpesan mendukung sesi yang memungkinkan produser untuk mengelompokkan pesan bersama-sama dan memastikan bahwa semuanya ditangani oleh konsumen yang sama. Mekanisme ini dapat digunakan dengan pesan yang diprioritaskan (jika didukung) untuk mengimplementasikan bentuk pengurutan pesan yang mengirimkan pesan secara berurutan dari produsen ke konsumen tunggal.

Desain beban kerja

Arsitek harus mengevaluasi bagaimana pola Competing Consumers dapat digunakan dalam desain beban kerja mereka untuk mengatasi tujuan dan prinsip yang tercakup dalam pilar Azure Well-Architected Framework. Contohnya:

Pilar Bagaimana pola ini mendukung tujuan pilar
Keputusan desain keandalan membantu beban kerja Anda menjadi tahan terhadap kerusakan dan untuk memastikan bahwa keputusan tersebut pulih ke status berfungsi penuh setelah kegagalan terjadi. Pola ini membangun redundansi dalam pemrosesan antrean dengan memperlakukan konsumen sebagai replika, sehingga kegagalan instans tidak mencegah konsumen lain memproses pesan antrean.

- RE:05 Redundansi
- Pekerjaan latar belakang RE:07
Pengoptimalan Biaya difokuskan untuk mempertahankan dan meningkatkan pengembalian beban kerja Anda pada investasi. Pola ini dapat membantu Anda mengoptimalkan biaya dengan mengaktifkan penskalaan yang didasarkan pada kedalaman antrean, turun ke nol saat antrean kosong. Ini juga dapat mengoptimalkan biaya dengan memungkinkan Anda membatasi jumlah maksimum instans konsumen bersamaan.

- Pengoptimalan LAJU CO:05
- Biaya komponen CO:07
Efisiensi Performa membantu beban kerja Anda memenuhi tuntutan secara efisien melalui pengoptimalan dalam penskalaan, data, kode. Mendistribusikan beban di semua simpul konsumen meningkatkan pemanfaatan dan penskalaan dinamis berdasarkan kedalaman antrean meminimalkan provisi berlebih.

- PE:05 Penskalaan dan pemartisian
- Pe:07 Kode dan infrastruktur

Seperti halnya keputusan desain apa pun, pertimbangkan tradeoff terhadap tujuan pilar lain yang mungkin diperkenalkan dengan pola ini.

Contoh

Azure menyediakan Antrean Azure Service Bus dan pemicu antrean Azure Function yang, jika digabungkan, adalah implementasi langsung dari pola desain cloud ini. Azure Functions terintegrasi dengan Azure Service Bus melalui pemicu dan pengikatan data. Berintegrasi dengan Azure Service Bus memungkinkan Anda untuk membangun fungsi yang menggunakan pesan antrean yang dikirim oleh penerbit. Aplikasi penerbitan akan memposting pesan ke antrean, dan konsumen, yang diimplementasikan sebagai Azure Functions, dapat mengambil pesan dari antrean ini dan menanganinya.

Untuk ketahanan, antrean Azure Service Bus memungkinkan konsumen menggunakan mode PeekLock saat mengambil pesan dari antrean; mode ini tidak benar-benar menghapus pesan, tetapi hanya menyembunyikannya dari konsumen lain. Runtime Azure Functions menerima pesan dalam mode PeekLock, jika fungsi berhasil selesai maka sistem memanggil Selesai pada pesan, atau mungkin memanggil Abaikan jika fungsi gagal, dan pesan akan terlihat lagi, memungkinkan konsumen lain untuk mengambilnya. Jika fungsi berjalan lebih lama dari batas waktu PeekLock, kunci akan diperbarui secara otomatis asalkan fungsi masih berjalan.

Azure Functions dapat memperluas/memperkecil skala berdasarkan kedalaman antrean, semuanya bertindak sebagai konsumen antrean yang bersaing. Jika beberapa instans fungsi dibuat, mereka semua bersaing dengan menarik dan memproses pesan secara independen.

Untuk informasi mendetail tentang menggunakan antrean Azure Service Bus, lihat Antrean, topik, dan langganan Service Bus.

Untuk informasi tentang Azure Functions yang dipicu antrean, lihat pemicu Azure Service Bus untuk Azure Functions.

Kode berikut menunjukkan bagaimana Anda dapat membuat pesan baru dan mengirimkannya ke Antrean Azure Service Bus menggunakan instans ServiceBusClient.

private string serviceBusConnectionString = ...;
...

  public async Task SendMessagesAsync(CancellationToken  ct)
  {
   try
   {
    var msgNumber = 0;

    var serviceBusClient = new ServiceBusClient(serviceBusConnectionString);

    // create the sender
    ServiceBusSender sender = serviceBusClient.CreateSender("myqueue");

    while (!ct.IsCancellationRequested)
    {
     // Create a new message to send to the queue
     string messageBody = $"Message {msgNumber}";
     var message = new ServiceBusMessage(messageBody);

     // Write the body of the message to the console
     this._logger.LogInformation($"Sending message: {messageBody}");

     // Send the message to the queue
     await sender.SendMessageAsync(message);

     this._logger.LogInformation("Message successfully sent.");
     msgNumber++;
    }
   }
   catch (Exception exception)
   {
    this._logger.LogException(exception.Message);
   }
  }

Contoh kode berikut memperlihatkan konsumen, yang ditulis sebagai C# Azure Function, yang membaca metadata pesan dan mencatat pesan Antrean Azure Service Bus. Perhatikan bagaimana atribut ServiceBusTrigger digunakan untuk mengikatnya ke Antrean Azure Service Bus.

[FunctionName("ProcessQueueMessage")]
public static void Run(
    [ServiceBusTrigger("myqueue", Connection = "ServiceBusConnectionString")]
    string myQueueItem,
    Int32 deliveryCount,
    DateTime enqueuedTimeUtc,
    string messageId,
    ILogger log)
{
    log.LogInformation($"C# ServiceBus queue trigger function consumed message: {myQueueItem}");
    log.LogInformation($"EnqueuedTimeUtc={enqueuedTimeUtc}");
    log.LogInformation($"DeliveryCount={deliveryCount}");
    log.LogInformation($"MessageId={messageId}");
}

Langkah berikutnya

  • Primer Olahpesan Asinkron. Antrean pesan adalah mekanisme komunikasi yang asinkron. Jika layanan konsumen perlu mengirim balasan ke aplikasi, mungkin perlu mengimplementasikan suatu bentuk pesan respons. Primer Olahpesan Asinkron memberikan informasi tentang cara mengimplementasikan pesan permintaan/balasan menggunakan antrean pesan.

  • Panduan Penskalaan Otomatis. Mungkin saja untuk memulai dan menghentikan instans layanan konsumen karena panjang dari antrean aplikasi yang mengirim pesan bisa bervariasi. Penskalaan otomatis dapat membantu mempertahankan throughput selama masa pemrosesan puncak.

Pola dan panduan berikut mungkin relevan saat mengimplementasikan pola ini:

  • Pola Konsolidasi Sumber Daya Komputasi. Mungkin saja untuk mengkonsolidasikan beberapa instans layanan konsumen ke dalam satu proses untuk mengurangi biaya dan overhead manajemen. Pola Konsolidasi Sumber Daya Komputasi menjelaskan manfaat dan kerugian dari mengikuti pendekatan ini.

  • Pola Pemerataan Beban Berdasarkan Antrean. Memperkenalkan antrean pesan dapat menambah ketahanan ke sistem, memungkinkan instans layanan untuk menangani volume permintaan yang sangat beragam dari instans aplikasi. Antrean pesan bertindak sebagai buffer yang meratakan beban. Pola Pemerataan Beban Berbasis Antrean menjelaskan skenario ini secara lebih rinci.