Transfer, kunci, dan penyelesaian pesan

Kemampuan utama broker pesan seperti Bus Layanan adalah menerima pesan ke dalam antrean atau topik dan menjaganya tetap tersedia untuk diambil di lain waktu. Kirim adalah istilah yang umum digunakan untuk mentransfer pesan ke broker pesan. Terima adalah istilah yang umum digunakan untuk mentransfer pesan ke klien yang mengambil.

Ketika klien mengirim pesan, biasanya ingin tahu apakah pesan ditransfer dengan benar dan diterima oleh broker atau apakah terjadi semacam kesalahan. Pengakuan positif atau negatif ini menyelesaikan pemahaman klien dan broker tentang status transfer pesan. Oleh karena itu, ini disebut sebagai penyelesaian.

Demikian juga, ketika broker mentransfer pesan ke klien, broker dan klien ingin membuat pemahaman tentang apakah pesan berhasil diproses dan oleh karena itu dapat dihapus, atau apakah pengiriman atau pemrosesan pesan gagal, dan dengan demikian pesan mungkin harus dikirim lagi.

Menyelesaikan operasi kirim

Dengan salah satu klien Azure Service Bus API yang didukung, operasi kirim ke dalam Service Bus selalu diselesaikan secara eksplisit, yang berarti bahwa operasi API menunggu hasil penerimaan dari Service Bus tiba, dan kemudian menyelesaikan operasi kirim.

Jika pesan ditolak oleh Azure Service Bus, penolakan berisi indikator kesalahan dan teks disertai id-pelacakan di dalamnya. Penolakan juga menyertakan informasi tentang apakah operasi dapat dicoba lagi agar berhasil. Pada klien, informasi ini diubah menjadi pengecualian dan dinaikkan ke pengguna operasi kirim. Jika pesan diterima, operasi akan selesai secara diam-diam.

Advanced Messaging Queuing Protocol (AMQP) adalah satu-satunya protokol yang didukung untuk klien .NET Standard, Java, JavaScript, Python, dan Go. Untuk klien .NET Framework, Anda dapat menggunakan Bus Layanan Messaging Protocol (SBMP) atau AMQP. Saat Anda menggunakan protokol AMQP, transfer pesan dan penyelesaian disalurkan dan asinkron. Sebaiknya Anda menggunakan varian API model pemrograman asinkron.

Pada 30 September 2026, kami akan menghentikan pustaka Azure Bus Layanan SDK WindowsAzure.ServiceBus, Microsoft.Azure.ServiceBus, dan com.microsoft.azure.servicebus, yang tidak sesuai dengan panduan Azure SDK. Kami juga akan mengakhiri dukungan protokol SBMP, sehingga Anda tidak akan lagi dapat menggunakan protokol ini setelah 30 September 2026. Migrasikan ke pustaka Azure SDK terbaru, yang menawarkan pembaruan keamanan penting dan kemampuan yang ditingkatkan, sebelum tanggal tersebut.

Meskipun pustaka lama masih dapat digunakan melebihi 30 September 2026, pustaka tersebut tidak akan lagi menerima dukungan dan pembaruan resmi dari Microsoft. Untuk informasi selengkapnya, lihat pengumuman penghentian dukungan.

Pengirim dapat memasukkan beberapa pesan di kabel dengan urutan yang cepat tanpa harus menunggu setiap pesan dibenarkan, seperti halnya dengan protokol SBMP atau dengan HTTP 1.1. Operasi pengiriman asinkron tersebut selesai karena masing-masing pesan diterima dan disimpan, pada entitas yang dipartisi atau saat operasi pengiriman ke entitas yang berbeda tumpang tindih. Penyelesaian mungkin juga terjadi dari urutan pengiriman asli.

Strategi untuk menangani hasil operasi pengiriman dapat memiliki dampak terhadap performa aplikasi Anda. Contoh dalam bagian ini ditulis dalam C# dan berlaku untuk java futures, Java monos, JavaScript promises, dan konsep yang setara dalam bahasa pemrogram lain.

Jika aplikasi menghasilkan rentetan pesan, diilustrasikan di sini dengan loop biasa, dan harus menunggu penyelesaian setiap operasi pengiriman sebelum mengirim pesan berikutnya, seperti bentuk API sinkron atau asinkron, mengirim 10 pesan hanya selesai setelah 10 round-trip penuh berurutan untuk penyelesaian.

Dengan jarak latensi pulang-pergi 70 milidetik (TCP) yang diasumsikan dari situs lokal untuk Bus Layanan dan hanya memberikan 10 md untuk Bus Layanan menerima dan menyimpan setiap pesan, perulangan berikut memakan waktu setidaknya 8 detik, tidak menghitung waktu transfer payload atau potensi efek kemacetan rute:

for (int i = 0; i < 10; i++)
{
    // creating the message omitted for brevity
    await sender.SendMessageAsync(message);
}

Jika aplikasi memulai 10 operasi pengiriman asinkron berturut-turut dan menunggu penyelesaian masing-masing secara terpisah, waktu round-trip untuk 10 operasi pengiriman tersebut tumpang tindih. 10 pesan ditransfer berturut-turut, bahkan berpotensi berbagi bingkai TCP, dan durasi transfer keseluruhan sangat bergantung pada waktu terkait jaringan yang diperlukan untuk mentransfer pesan ke broker.

Dengan membuat asumsi yang sama seperti perulangan sebelumnya, total waktu eksekusi yang tumpang tindih untuk perulangan berikut mungkin akan tetap berada di bawah satu detik:

var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
    tasks.Add(sender.SendMessageAsync(message));
}
await Task.WhenAll(tasks);

Hal penting yang perlu diperhatikan bahwa semua model pemrograman asinkron menggunakan beberapa bentuk berbasis memori, antrean kerja tersembunyi yang menahan tertundanya sebuah operasi. Ketika API pengiriman kembali, tugas kirim diantrekan dalam antrean kerja tersebut, tetapi gerakan protokol hanya dimulai setelah giliran tugas dijalankan. Untuk kode yang cenderung mendorong ledakan pesan dan di mana keandalan menjadi perhatian, perhatian harus diambil bahwa tidak terlalu banyak pesan dimasukkan "dalam penerbangan" sekaligus, karena semua pesan yang dikirim mengambil memori sampai mereka dimasukkan ke kabel.

Semaphore, seperti yang diperlihatkan dalam cuplikan kode berikut dalam C# adalah objek sinkronisasi yang mengaktifkan pembatasan tingkat aplikasi tersebut saat diperlukan. Penggunaan semaphore ini memungkinkan maksimal 10 pesan dimasukkan dalam penerbangan sekaligus. Salah satu dari 10 kunci semafor yang tersedia yaitu sudah diambil sebelum pengiriman dan dikeluarkan saat pengiriman telah selesai. Perulangan ke-11 menunggu hingga setidaknya salah satu operasi pengiriman sebelumnya selesai, lalu membuat kuncinya tersedia:

var semaphore = new SemaphoreSlim(10);

var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
    await semaphore.WaitAsync();

    tasks.Add(sender.SendMessageAsync(message).ContinueWith((t)=>semaphore.Release()));
}
await Task.WhenAll(tasks);

Aplikasi tidak akan pernah memulai operasi pengiriman asinkron dengan cara "picu dan lupakan" tanpa mengambil hasil operasi. Tindakan ini dapat memuat antrean tugas internal dan tak terlihat hingga memori tidak mencukupi, dan mencegah aplikasi mendeteksi kesalahan pengiriman:

for (int i = 0; i < 10; i++)
{
    sender.SendMessageAsync(message); // DON’T DO THIS
}

Dengan klien AMQP tingkat rendah, Bus Layanan juga menerima transfer "presettled". Transfer yang telah ditentukan sebelumnya adalah operasi fire-and-forget yang hasilnya, bagaimanapun, tidak dilaporkan kembali ke klien dan pesan dianggap diselesaikan saat dikirim. Kurangnya umpan balik pada klien juga berarti bahwa tidak ada data yang siap digunakan untuk di diagnostik, yang berarti bahwa mode ini tidak memenuhi syarat untuk mendapatkan bantuan melalui dukungan Azure.

Menyelesaikan operasi penerimaan

Untuk operasi penerimaan, klien Azure Service Bus API mengaktifkan dua mode eksplisit yang berbeda: Receive-and-Delete dan Intip-Kunci.

ReceiveAndDelete

Mode Terima dan Hapus memberi tahu broker untuk mempertimbangkan semua pesan yang dikirimnya ke klien penerima sebagaimana diselesaikan saat dikirim. Itu berarti bahwa pesan dianggap dikonsumsi segera setelah broker meletakkannya ke kawat. Jika transfer pesan gagal, pesan akan hilang.

Bagian terbalik dari mode ini adalah bahwa penerima tidak perlu mengambil tindakan lebih lanjut terhadap sebuah pesan dan juga tidak diperlambat dengan menunggu hasil penyelesaian. Jika data yang terkandung dalam setiap pesan memiliki nilai rendah dan/atau hanya bermakna selama waktu yang sangat singkat, mode ini adalah pilihan yang wajar.

PeekLock

Mode Peek-Lock memberi tahu broker bahwa klien penerima ingin menyelesaikan pesan yang diterima secara eksplisit. Pesan dibuat tersedia bagi penerima untuk kemudian diproses, sembari ditahan dengan penguncian eksklusif dalam layanan sehingga penerima lain yang bersaing tidak dapat melihatnya. Durasi kunci awalnya ditentukan pada tingkat antrean atau langganan dan dapat diperpanjang oleh klien yang memiliki kunci, melalui operasi RenewMessageLockAsync . Untuk detail tentang perpanjangan kunci, lihat bagian Memperpanjang kunci dalam artikel ini.

Jika pesan dikunci, klien penerima lain dari antrean atau langganan yang sama dapat memulai penguncian dan mengambil pesan berikutnya yang tersedia yang tidak dikunci secara aktif. Ketika kunci pada pesan dirilis secara eksplisit atau ketika kunci kedaluwarsa, pesan ditempatkan di atau dekat bagian depan urutan pengambilan untuk redelivery.

Jika pesan berulang kali dirilis oleh penerima atau mereka membiarkan kunci berlalu selama beberapa kali yang ditentukan (Jumlah Pengiriman Maks), pesan akan otomatis dihapus dari antrean atau langganan dan dimasukkan ke dalam antrean surat mati terkait.

Klien penerima memulai penyelesaian pesan yang diterima dengan pengakuan positif saat memanggil API Lengkap untuk pesan. Hal ini menunjukkan kepada broker bahwa pesan telah berhasil diproses dan pesan dihapus dari antrian atau langganan. Broker membalas niat penyelesaian penerima dengan balasan yang menunjukkan apakah penyelesaian dapat dilakukan.

Ketika klien penerima gagal memproses pesan tetapi ingin pesan dikirim ulang, klien penerima dapat secara eksplisit meminta pesan untuk dirilis dan dibuka kuncinya secara instan dengan memanggil API Abaikan untuk pesan atau tidak dapat melakukan apa pun dan membiarkan kunci berlalu.

Jika klien penerima gagal memproses pesan dan tahu bahwa mengirim ulang pesan dan mencoba kembali operasi tidak akan membantu, itu dapat menolak pesan, yang memindahkannya ke dalam antrean surat mati dengan memanggil DeadLetter API pada pesan, yang juga memungkinkan pengaturan properti kustom termasuk kode alasan yang dapat diambil dengan pesan dari antrean surat mati.

Catatan

Sub-antrean surat mati ada untuk antrean atau langganan topik hanya ketika Anda mengaktifkan fitur surat mati untuk antrean atau langganan.

Kasus khusus penyelesaian ditangguhkan, yang dibahas dalam artikel terpisah.

Operasi Complete, , DeadLetteratau RenewLock mungkin gagal karena masalah jaringan, jika kunci yang ditahan telah kedaluwarsa, atau ada kondisi sisi layanan lain yang mencegah penyelesaian. Dalam salah satu kasus terakhir, layanan mengirimkan pengakuan negatif yang muncul sebagai pengecualian di klien API. Jika alasannya adalah terputusnya koneksi jaringan, kunci akan diturunkan sejak Azure Service Bus tidak mendukung pemulihan tautan AMQP yang ada pada koneksi yang berbeda.

Jika Complete gagal, yang biasanya terjadi di akhir penanganan pesan dan dalam beberapa kasus setelah menit pekerjaan pemrosesan, aplikasi penerima dapat memutuskan apakah akan mempertahankan status pekerjaan dan mengabaikan pesan yang sama ketika dikirimkan untuk kedua kalinya, atau apakah akan merotasi hasil kerja dan mencoba kembali saat pesan dikirimkan ulang.

Mekanisme umum untuk mengidentifikasi pengiriman pesan duplikat adalah dengan memeriksa id-pesan, yang dapat dan harus diatur oleh pengirim ke nilai unik, mungkin disesuaikan dengan pengidentifikasi dari proses asal. Penjadwal pekerjaan kemungkinan akan mengatur identitas pesan ke pengidentifikasi pekerjaan yang ingin ditetapkan kepada pekerja dengan pekerja yang ditentukan, dan pekerja akan mengabaikan kejadian kedua dari penetapan pekerjaan jika pekerjaan tersebut sudah dilakukan.

Penting

Penting untuk dicatat bahwa kunci yang diperoleh PeekLock atau SessionLock pada pesan tidak stabil dan mungkin hilang dalam kondisi berikut

  • Pembaruan Layanan
  • Pembaruan OS
  • Mengubah properti pada entitas (Antrean, Topik, Langganan) sambil mempertahankan kunci.

Ketika kunci hilang, Azure Bus Layanan akan menghasilkan MessageLockLostException atau SessionLockLostException, yang akan muncul di aplikasi klien. Dalam hal ini, logika coba lagi default klien akan otomatis memicu dan mencoba kembali operasi.

Memperpanjang durasi kunci

Nilai default untuk durasi kunci adalah 1 menit. Anda dapat menentukan nilai durasi kunci yang berbeda di tingkat antrean atau langganan. Klien yang memiliki kunci dapat memperpanjang durasi kunci pesan dengan menggunakan metode pada objek penerima. Sebagai gantinya, Anda dapat menggunakan fitur perpanjangan kunci otomatis di mana Anda inginkan agar durasi kunci tetap diperpanjang.

Yang terbaik adalah mengatur durasi kunci ke sesuatu yang lebih tinggi dari waktu pemrosesan normal Anda, sehingga Anda tidak perlu memperbarui kunci. Nilai maksimum adalah 5 menit, jadi Anda perlu memperbarui kunci jika Anda ingin memilikinya lebih lama. Memiliki durasi kunci yang lebih lama daripada yang diperlukan juga memiliki beberapa implikasi. Misalnya, ketika klien Anda berhenti bekerja, pesan hanya akan tersedia lagi setelah durasi kunci berlalu.

Langkah berikutnya