Dead Letter Queue
Route repeatedly failed KubeMQ Queue messages to a dead-letter queue with the C++ SDK for later inspection.
Overview
A dead-letter queue (DLQ) gives a poison message somewhere to go instead of looping through consumers forever. When a message keeps failing — a malformed payload, a downstream outage, a handler bug — retrying it forever wastes consumer cycles and blocks everything behind it. A DLQ takes that decision out of your hands: past a set number of failed attempts, the broker diverts the message to a separate channel instead of retrying it again.
Routing runs on two settings attached to the message: SetMaxReceiveCount() and SetMaxReceiveQueue(). Every failed delivery — a nack, a reject, or an expired visibility window — increments the receive count; past the threshold, the broker reroutes the message to the DLQ instead of redelivering it. The DLQ itself is an ordinary queue, consumed like any other channel.
Gotchas: the DLQ doesn't drain itself — a dedicated consumer must watch it. The count increments on any failed delivery, not just deliberate rejections — a slow consumer that lets the visibility window lapse counts the same as an explicit nack. A typo in the DLQ channel name quietly creates an unrelated channel instead of failing loudly.
Prerequisites
- KubeMQ server running on
localhost:50000 - C++ SDK installed (vcpkg or CMake FetchContent)
- C++17 compiler (GCC 9+, Clang 9+, MSVC 2019+)
Code
// Example: queues/dead_letter_queue
//
// Demonstrates configuring a dead-letter queue (DLQ) for messages that
// exceed the maximum receive count. After the max attempts, messages
// are moved to the specified DLQ channel.
//
// Channel: cpp-queues.dead-letter-queue
// Client ID: cpp-queues-dead-letter-queue-client
//
// Run with a KubeMQ server on localhost:50000
// (see https://docs.kubemq.io/deploy).
#include <kubemq/kubemq.h>
#include <iostream>
int main() {
std::cout << "[1] Connecting to localhost:50000" << std::endl;
kubemq::ClientOptions options;
options.set_address("localhost", 50000);
options.set_client_id("cpp-queues-dead-letter-queue-client");
auto client_result = kubemq::Client::Create(options);
if (!client_result.ok()) {
std::cerr << "[ERROR] Failed to create client: " << client_result.status().message()
<< std::endl;
return 1;
}
auto& client = *client_result;
std::string channel = "cpp-queues.dead-letter-queue";
std::string dlq_channel = channel + ".dlq";
// Send a message with dead-letter queue configuration.
// After 3 failed receive attempts, the message is moved to the DLQ.
std::cout << "[2] Sending message with DLQ config (max_receives=3, dlq=" << dlq_channel << ")"
<< std::endl;
auto msg_result = kubemq::QueueMessage::Builder()
.SetChannel(channel)
.SetBody("message with DLQ")
.SetMaxReceiveCount(3)
.SetMaxReceiveQueue(dlq_channel)
.Build();
if (!msg_result.ok()) {
std::cerr << "[ERROR] Build message: " << msg_result.status().message() << std::endl;
return 1;
}
auto send_result = client->SendQueueMessage(*msg_result);
if (!send_result.ok()) {
std::cerr << "[ERROR] SendQueueMessage: " << send_result.status().message() << std::endl;
return 1;
}
if (send_result->is_error) {
std::cerr << "[ERROR] Send failed: " << send_result->error << std::endl;
return 1;
}
std::cout << "[3] DLQ message sent: id=" << send_result->message_id
<< " (max_receives=3, dlq=" << dlq_channel << ")" << std::endl;
// Close the client explicitly.
// Note: The Client destructor also calls Close(), but explicit
// cleanup is shown here for clarity and to match Go's defer pattern.
auto close_status = client->Close();
if (!close_status.ok()) {
std::cerr << "[ERROR] Close failed: " << close_status.message() << std::endl;
return 1;
}
std::cout << "[4] Client closed" << std::endl;
return 0;
}How It Works
- Configures messages with
SetMaxReceiveCount()andSetMaxReceiveQueue(). - After exceeding the max receive count, messages are moved to the dead-letter queue.
- The dead-letter queue is a regular queue channel that collects failed messages.
- Useful for isolating and debugging messages that cannot be processed.
Related
Was this page helpful?