صف پیام‌های ناموفق (Dead Letter Queue یا DLQ) مسیری برای نگهداری پیام‌هایی است که در صف اصلی پس از چند تلاش، خطای غیرقابل بازیابی یا رسیدن به محدودیت زمانی دیگر قابل پردازش نیستند. هدف DLQ این است که یک پیام معیوب کل صف را متوقف نکند و بررسی علت شکست ممکن باشد.

چه پیام‌هایی وارد DLQ می‌شوند؟

  • پیام با Payload نامعتبر که Consumer نمی‌تواند آن را پردازش کند
  • پیام پس از پایان تعداد تلاش مجدد
  • پیام منقضی‌شده بر اساس سیاست TTL یا Broker
  • پیامی که مصرف‌کننده صریحا رد می‌کند و Broker آن را به صف خطا منتقل می‌کند

نمونه تنظیم RabbitMQ با Dead-letter Exchange

import pika
ch = connection.channel()
ch.exchange_declare(exchange="orders.dlx", exchange_type="direct", durable=True)
ch.queue_declare(queue="orders.dlq", durable=True)
ch.queue_bind(queue="orders.dlq", exchange="orders.dlx", routing_key="failed")
ch.queue_declare(queue="orders", durable=True, arguments={
    "x-dead-letter-exchange": "orders.dlx",
    "x-dead-letter-routing-key": "failed",
})

تفاوت با Failed Jobs در Laravel

لاراول می‌تواند Jobهای شکست‌خورده را در Failed Job Storage ثبت کند و با دستورهای مدیریتی بررسی کند. این سازوکار با DLQ اختصاصی Broker یکسان نیست، هرچند هدف عملیاتی مشابهی دارند.

php artisan queue:failed
php artisan queue:retry all

از DLQ به صف اصلی بی‌محابا برنگردانید

پیش از Retry مجدد، علت خطا و نسخه Payload را بررسی کنید. بازپخش دسته‌ای بدون کنترل می‌تواند همان خطا را تکرار یا اثر تجاری ناخواسته ایجاد کند.

صفحات سازوکار تلاش مجدد، آیدمپوتنسی و مسیج بروکر مکمل‌اند.