Pengakuan Pengguna & Giliran Semula
Kuasai pengakuan pengguna dan pelajari cara memasukkan semula mesej ke dalam baris gilir apabila pemprosesan gagal. Reka bentuk pengguna yang tahan terhadap kegagalan dan boleh mengendalikan ralat dengan baik.
Pengakuan Pengguna & Giliran Semula 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.
Penggunaan Mesej yang Boleh Dipercayai
Dalam sistem teragih, memastikan mesej diproses dengan betul adalah penting. Apakah yang berlaku jika pengguna ranap ketika pemprosesan sedang berlangsung? Atau jika mesej menyebabkan ralat?
Pelajaran ini meneroka pengakuan pengguna dan penghantaran semula ke baris gilir, iaitu teknik penting untuk membina pengguna mesej yang tahan terhadap kegagalan.
ACK: Jabat Tangan
Pengakuan pengguna (ACK) ialah isyarat yang dihantar oleh pengguna kembali kepada RabbitMQ. Isyarat ini memberitahu broker: "Saya telah menerima dan memproses mesej ini dengan berjaya."
- Tanpa ACK, RabbitMQ menganggap mesej itu belum diproses.
- Mekanisme ini mencegah kehilangan mesej jika pengguna gagal sebelum menyelesaikan tugasnya.
ACK Automatik berbanding Manual
RabbitMQ menyediakan dua cara untuk mengakui mesej:
- Automatik (
autoAck=true): Mesej diakui sebaik sahaja dihantar kepada pengguna. Mudah, tetapi berisiko jika pemprosesan gagal. - Manual (
autoAck=false): Pengguna menghantar ACK secara nyata selepas pemprosesan berjaya. Ini ialah tetapan lalai dan disyorkan untuk sistem yang boleh dipercayai.
Kita akan memfokuskan pengakuan manual untuk mendapatkan keteguhan.
Menghantar Mesej (Pengeluar)
Mari sediakan pengeluar Java yang mudah untuk menghantar mesej. Mesej ini akan digunakan kemudian, dan kita akan menggunakan pengakuan manual.
Jalankan kod ini untuk menghantar mesej "Hello RabbitMQ!".
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.nio.charset.StandardCharsets;
public class MyProducer {
private final static String QUEUE_NAME = "ack_queue";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost"); // Connect to local RabbitMQ
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello RabbitMQ!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
System.out.println(" [x] Sent '" + message + "'");
}
}
}Pengakuan Manual dalam Tindakan
Sekarang, mari cipta pengguna yang menggunakan pengakuan manual. Perhatikan bahawa parameter autoAck ditetapkan kepada false semasa penggunaan mesej.
Panggilan channel.basicAck() mengesahkan pemprosesan yang berjaya.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import java.nio.charset.StandardCharsets;
public class MyConsumerAck {
private final static String QUEUE_NAME = "ack_queue";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
System.out.println(" [x] Received '" + message + "'");
try {
// Simulate processing work
Thread.sleep(1000);
System.out.println(" [x] Done processing '" + message + "'");
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); // Manual ACK!
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println(" [!] Processing interrupted.");
// In a real app, you might re-queue or handle error
}
};
// autoAck is set to false for manual acknowledgements
channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});
}
}Apabila Pemprosesan Gagal
Apakah yang berlaku jika pengguna kita menghadapi ralat semasa memproses mesej? Jika kita hanya menggunakan basicAck, mesej itu akan hilang walaupun pemprosesan belum selesai.
RabbitMQ menyediakan cara untuk memaklumkan broker bahawa mesej tidak dapat diproses dengan berjaya, lalu memberikan kita pilihan untuk mengendalikannya.
Menghantar Semula Mesej yang Gagal ke Baris Gilir
Jika pemprosesan mesej gagal disebabkan ralat sementara (contohnya, sambungan pangkalan data terputus), anda mungkin mahu mencubanya semula kemudian. Gunakan channel.basicNack(deliveryTag, multiple, requeue) atau channel.basicReject(deliveryTag, requeue).
- Menetapkan
requeuekepadatrueakan menghantar mesej kembali ke baris gilir untuk diambil oleh pengguna lain.
Jalankan pengguna ini. Pengguna ini akan sengaja gagal dua kali kemudian memproses mesej dengan berjaya.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;
public class MyConsumerRequeue {
private final static String QUEUE_NAME = "ack_queue";
private static int attemptCount = 0;
public static void main(String[] argv) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
long deliveryTag = delivery.getEnvelope().getDeliveryTag();
System.out.println(" [x] Received '" + message + "' (Attempt: " + (++attemptCount) + ")");
try {
if (attemptCount <= 2) { // Simulate failure for first 2 attempts
throw new RuntimeException("Simulated processing error!");
}
// Simulate successful processing
Thread.sleep(1000);
System.out.println(" [x] Successfully processed '" + message + "'");
channel.basicAck(deliveryTag, false); // ACK on success
} catch (Exception e) {
System.err.println(" [!] Error processing '" + message + "': " + e.getMessage());
channel.basicNack(deliveryTag, false, true); // NACK and requeue!
System.out.println(" [!] Message '" + message + "' requeued.");
}
};
channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});
}
}Membuang Mesej Bermasalah
Kadang-kadang, mesej mempunyai kecacatan asas dan akan *sentiasa* menyebabkan ralat. Menghantarnya semula ke baris gilir berulang kali tidak berguna dan boleh menyebabkan gelung "mesej beracun".
Dalam keadaan sedemikian, tetapkan requeue kepada false. Tindakan ini membuang mesej daripada baris gilir. Selalunya, mesej ini dihantar ke Dead Letter Exchange (DLX) untuk diperiksa kemudian, tetapi kita akan membincangkan DLX dalam pelajaran akan datang.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;
public class MyConsumerReject {
private final static String QUEUE_NAME = "ack_queue";
public static void main(String[] argv) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
long deliveryTag = delivery.getEnvelope().getDeliveryTag();
System.out.println(" [x] Received '" + message + "'");
// Simulate an unrecoverable error
System.err.println(" [!] Fatal error for '" + message + "'. Discarding.");
channel.basicNack(deliveryTag, false, false); // NACK and DO NOT requeue!
System.out.println(" [!] Message '" + message + "' rejected (not requeued).");
};
channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});
}
}Pengguna Idempoten
Apabila anda menghantar semula mesej ke baris gilir, ada kemungkinan pengguna memproses mesej yang sama beberapa kali.
Amat penting untuk mereka bentuk pengguna anda supaya idempoten. Ini bermaksud pemprosesan mesej yang sama dua kali (atau lebih) menghasilkan keputusan yang sama seperti pemprosesan sekali, tanpa kesan sampingan yang tidak diingini.
Semakan Kebolehpercayaan
Pertimbangkan pengguna RabbitMQ yang dikonfigurasikan dengan pengakuan manual. Jika mesej diterima tetapi pengguna ranap *sebelum* memanggil channel.basicAck() atau channel.basicNack(), apakah yang biasanya berlaku kepada mesej itu?
Imbas Kembali: Membina Pengguna yang Boleh Dipercayai
Anda telah mempelajari cara menjadikan pengguna RabbitMQ anda berdaya tahan:
- Pengakuan Manual: Memberikan pengguna kawalan terhadap nasib mesej.
- Penghantaran Semula ke Baris Gilir: Cuba semula mesej yang mengalami kegagalan sementara menggunakan
basicNack(..., true). - Pembuangan: Mencegah gelung mesej beracun dengan
basicNack(..., false). - Idempoten: Mereka bentuk pengguna supaya dapat mengendalikan penghantaran pendua dengan baik.
Teknik ini merupakan asas untuk membina sistem pemesejan yang kukuh 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 “Pengakuan Pengguna & Giliran Semula” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Pemesejan RabbitMQ & Sistem Tak Segerak, termasuk “Pengakuan Pengguna & Giliran Semula”, 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 “Pengakuan Pengguna & Giliran Semula”?
Kuasai pengakuan pengguna dan pelajari cara memasukkan semula mesej ke dalam baris gilir apabila pemprosesan gagal. Reka bentuk pengguna yang tahan terhadap kegagalan dan boleh mengendalikan ralat de… 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 “Pengakuan Pengguna & Giliran Semula” 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
- Mesej dan Baris Gilir Berterusan
- Pengesahan Penerbit untuk Kebolehpercayaan
- Pengakuan Pengguna & Giliran Semula
- Urus Niaga vs Pengesahan Penerbit