Pertukaran Surat Mati (DLX)
Konfigurasikan Pertukaran Surat Mati untuk mengendalikan mesej yang tidak dapat dihantar atau diproses dengan jayanya. Laksanakan pengendalian ralat dan strategi pemprosesan semula mesej yang kukuh.
Pertukaran Surat Mati (DLX) ialah pelajaran Pemesejan RabbitMQ & Sistem Tak Segerak percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Pemesejan RabbitMQ & Sistem Tak Segerak, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Pemesejan RabbitMQ & Sistem Tak Segerak merangkumi sejumlah 4 pelajaran.
Apakah Itu Dead Letter Exchange?
Dalam penggiliran mesej, kadangkala mesej tidak dapat diproses dengan jayanya. Mesej itu mungkin tidak sah, atau pengguna mungkin mengalami kegagalan. Apakah yang berlaku kepada mesej 'bermasalah' ini?
Dead Letter Exchange (DLX) dalam RabbitMQ ialah mekanisme untuk mengendalikan mesej yang tidak dapat dihantar atau diproses. Ia seperti peti mel khas untuk mel yang 'tidak dapat dihantar'.
Apabila Mesej Tersasar
Mesej menjadi 'dead-letter' (dihantar kepada DLX) dalam keadaan tertentu:
- Ditolak oleh Pengguna: Pengguna menolak mesej secara jelas (menggunakan
basic.rejectataubasic.nack) dan menetapkanrequeuekepadafalse. - Tempoh TTL Mesej Tamat: Tempoh Time-To-Live (TTL) mesej tamat semasa mesej berada dalam baris gilir.
- Had Panjang Baris Gilir: Baris gilir mencapai panjang maksimum dan mesej baharu menyebabkan mesej lama dibuang.
- Mesej Tidak Boleh Dihala: Jika mesej diterbitkan kepada exchange dengan bendera wajib, tetapi tidak dapat dihalakan kepada mana-mana baris gilir, mesej itu juga boleh menjadi dead-letter. (Kurang lazim, tetapi boleh berlaku)
Konfigurasi Asas DLX
Untuk menggunakan DLX, anda perlu mengkonfigurasi baris gilir utama supaya menunjuk kepadanya. Hal ini dilakukan apabila anda mengisytiharkan baris gilir utama:
x-dead-letter-exchange: Nama exchange yang akan menerima mesej dead-letter.x-dead-letter-routing-key: Kunci penghalaan pilihan untuk digunakan semasa menerbitkan kepada DLX. Jika tidak ditetapkan, kunci penghalaan asal mesej dead-letter akan digunakan.
Anda juga perlu mengisytiharkan DLX itu sendiri dan 'baris gilir dead-letter' (DLQ) yang diikat kepada DLX.
Persediaan DLX dan Pengeluar (Contoh Nack)
Mari kita sediakan baris gilir utama yang menghantar mesej yang ditolak kepada DLX. Pengeluar ini mengisytiharkan DLX, baris gilir dead-letter (DLQ), dan mengikat kedua-duanya. Kemudian, pengeluar ini mengisytiharkan main_queue kita dan mengkonfigurasikannya untuk menggunakan DLX.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class DLXProducerNack {
private static final String MAIN_QUEUE_NAME = "main_nack_queue";
private static final String DLX_EXCHANGE_NAME = "dlx_exchange";
private static final String DLQ_QUEUE_NAME = "dlq_nack_queue";
private static final String DLQ_ROUTING_KEY = "dlq_nack_key";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 1. Declare DLX and DLQ
channel.exchangeDeclare(DLX_EXCHANGE_NAME, "topic", true);
channel.queueDeclare(DLQ_QUEUE_NAME, true, false, false, null);
channel.queueBind(DLQ_QUEUE_NAME, DLX_EXCHANGE_NAME, DLQ_ROUTING_KEY);
// 2. Declare main queue with DLX arguments
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", DLX_EXCHANGE_NAME);
args.put("x-dead-letter-routing-key", DLQ_ROUTING_KEY);
channel.queueDeclare(MAIN_QUEUE_NAME, true, false, false, args);
String message = "Message to be rejected!";
channel.basicPublish("", MAIN_QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
System.out.println(" [x] Sent '" + message + "' to " + MAIN_QUEUE_NAME);
}
}
}Pengguna dengan Penolakan Asas
Pengguna ini mendengar main_nack_queue. Apabila menerima mesej, pengguna ini menggunakan basicReject(deliveryTag, false) untuk menolaknya tanpa memasukkannya semula ke dalam baris gilir. Tindakan ini menghantar mesej kepada DLX yang telah dikonfigurasi. Pengguna ini juga mendengar DLQ untuk memaparkan mesej dead-letter tersebut.
Jalankan pengeluar daripada adegan sebelumnya, kemudian jalankan pengguna ini.
import com.rabbitmq.client.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class DLXConsumerNack {
private static final String MAIN_QUEUE_NAME = "main_nack_queue";
private static final String DLQ_QUEUE_NAME = "dlq_nack_queue";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// Consumer for the main queue, will reject messages
System.out.println(" [*] Waiting for messages in " + MAIN_QUEUE_NAME + ".");
DeliverCallback mainQueueDeliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
System.out.println(" [x] Received from " + MAIN_QUEUE_NAME + ": '" + message + "'");
System.out.println(" [x] Rejecting message. It should go to DLQ.");
channel.basicReject(delivery.getEnvelope().getDeliveryTag(), false); // Don't requeue
};
channel.basicConsume(MAIN_QUEUE_NAME, false, mainQueueDeliverCallback, consumerTag -> {});
// Consumer for the dead-letter queue
System.out.println(" [*] Waiting for messages in " + DLQ_QUEUE_NAME + " (DLQ).");
DeliverCallback dlqDeliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
System.out.println(" [DLQ] Received dead-lettered message: '" + message + "'");
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
};
channel.basicConsume(DLQ_QUEUE_NAME, false, dlqDeliverCallback, consumerTag -> {});
}
}DLX dengan TTL Mesej (Pengeluar)
Mesej juga boleh menjadi dead-letter jika tempohnya tamat. Pengeluar ini menghantar mesej dengan Time-To-Live (TTL) pendek selama 5 saat kepada baris gilir utama. Jika tiada pengguna memprosesnya dalam tempoh tersebut, mesej itu akan menjadi dead-letter.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.AMQP;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class DLXTTLProducer {
private static final String MAIN_QUEUE_NAME = "main_ttl_queue";
private static final String DLX_EXCHANGE_NAME = "dlx_exchange"; // Reuse DLX
private static final String DLQ_QUEUE_NAME = "dlq_ttl_queue"; // Separate DLQ for TTL
private static final String DLQ_ROUTING_KEY = "dlq_ttl_key";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// Declare DLX and DLQ (if not already done)
channel.exchangeDeclare(DLX_EXCHANGE_NAME, "topic", true);
channel.queueDeclare(DLQ_QUEUE_NAME, true, false, false, null);
channel.queueBind(DLQ_QUEUE_NAME, DLX_EXCHANGE_NAME, DLQ_ROUTING_KEY);
// Declare main queue with DLX arguments and message TTL
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", DLX_EXCHANGE_NAME);
args.put("x-dead-letter-routing-key", DLQ_ROUTING_KEY);
args.put("x-message-ttl", 5000); // Message TTL of 5 seconds
channel.queueDeclare(MAIN_QUEUE_NAME, true, false, false, args);
String message = "This message will expire!";
channel.basicPublish("", MAIN_QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
System.out.println(" [x] Sent '" + message + "' to " + MAIN_QUEUE_NAME);
System.out.println(" [x] Message has a TTL of 5 seconds. It will dead-letter if not consumed.");
}
}
}Memerhati Dead-Letter TTL (Pengguna)
Pengguna ini hanya mendengar baris gilir dead-letter (dlq_ttl_queue). Jalankan pengeluar daripada adegan sebelumnya, kemudian jalankan pengguna ini. Anda akan melihat mesej muncul dalam DLQ selepas TTL 5 saatnya tamat, walaupun tiada pengguna menolaknya.
import com.rabbitmq.client.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class DLXTTLConsumer {
private static final String DLQ_QUEUE_NAME = "dlq_ttl_queue";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// Consumer for the dead-letter queue for TTL messages
channel.queueDeclare(DLQ_QUEUE_NAME, true, false, false, null);
System.out.println(" [*] Waiting for dead-lettered messages in " + DLQ_QUEUE_NAME + ".");
System.out.println(" Run DLXTTLProducer first, then wait 5 seconds.");
DeliverCallback dlqDeliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
System.out.println(" [DLQ] Received expired dead-lettered message: '" + message + "'");
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
};
channel.basicConsume(DLQ_QUEUE_NAME, false, dlqDeliverCallback, consumerTag -> {});
}
}Penerokaan Mendalam Kunci Penghalaan DLX
Apabila mesej menjadi dead-letter, mesej itu diterbitkan kepada DLX. Kunci penghalaan yang digunakan untuk penerbitan ini adalah penting:
- Secara lalai, kunci penghalaan asal mesej akan digunakan.
- Jika anda menentukan
x-dead-letter-routing-keysemasa mengisytiharkan baris gilir utama, kunci baharu ini akan menggantikan kunci asal.
Hal ini membolehkan anda menghalakan mesej dead-letter kepada baris gilir dead-letter yang berbeza berdasarkan konteks asalnya atau jenis ralat tertentu.
Memproses Semula Mesej Dead-Letter
Tujuan DLX bukan sekadar menyimpan mesej yang gagal, tetapi juga menyediakan laluan untuk pemulihan. Strategi lazim untuk mengendalikan mesej dalam DLQ termasuk:
- Campur Tangan Manual: Memeriksa mesej dalam DLQ dan menerbitkannya semula secara manual selepas membaiki masalah asas.
- Pembalakan dan Amaran: Hanya merekodkan butiran mesej dead-letter dan mencetuskan alerts untuk siasatan.
- Perkhidmatan Percubaan Semula Automatik: Pengguna khusus untuk DLQ yang cuba memproses semula mesej selepas kelewatan, mungkin dengan masa menunggu yang meningkat secara eksponen.
- Perkhidmatan Ralat Berasingan: Menghalakan mesej dead-letter kepada perkhidmatan khusus yang direka semata-mata untuk pengendalian dan pelaporan ralat.
Semakan Pengetahuan DLX
Antara keadaan berikut, yang manakah boleh menyebabkan mesej menjadi dead-letter oleh RabbitMQ?
Imbas Kembali: Dead Letter Exchange
Dalam pelajaran ini, kita meneroka Dead Letter Exchange (DLX) dalam RabbitMQ. Anda telah mempelajari:
- DLX menyediakan mekanisme pengendalian ralat yang kukuh untuk mesej yang tidak boleh diproses.
- Mesej menjadi dead-letter disebabkan penolakan pengguna, tamat tempoh TTL atau had panjang baris gilir.
- Anda mengkonfigurasi baris gilir utama dengan
x-dead-letter-exchangedanx-dead-letter-routing-key. - Contoh praktikal menunjukkan cara menyediakan DLX untuk mesej yang ditolak dan tamat tempoh.
- Kita membincangkan strategi untuk memproses semula mesej daripada baris gilir dead-letter.
DLX ialah alat penting untuk membina sistem pemesejan yang berdaya tahan dan tahan terhadap kegagalan.
Pelajari Pemesejan RabbitMQ & Sistem Tak Segerak dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 11
- Pelajaran
- 44
Soalan Lazim
Adakah pelajaran “Pertukaran Surat Mati (DLX)” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Pemesejan RabbitMQ & Sistem Tak Segerak, termasuk “Pertukaran Surat Mati (DLX)”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Pemesejan RabbitMQ & Sistem Tak Segerak merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Pertukaran Surat Mati (DLX)”?
Konfigurasikan Pertukaran Surat Mati untuk mengendalikan mesej yang tidak dapat dihantar atau diproses dengan jayanya. Laksanakan pengendalian ralat dan strategi pemprosesan semula mesej yang kukuh. Anda berlatih Pemesejan RabbitMQ & Sistem Tak Segerak menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Pemesejan RabbitMQ & Sistem Tak Segerak?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Pemesejan RabbitMQ & Sistem Tak Segerak di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.
Berapa lamakah pelajaran “Pertukaran Surat Mati (DLX)” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Pemesejan RabbitMQ & Sistem Tak Segerak ini?
Ya. Setiap pelajaran Pemesejan RabbitMQ & Sistem Tak Segerak menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Pertukaran Headers secara Mendalam
- Pengikatan Pertukaran kepada Pertukaran
- Pertukaran Surat Mati (DLX)
- Pertukaran Alternatif untuk Mesej Tidak Boleh Dihalakan