本文目录导读:

针对 Laravel 中“死信”的处理,通常指的是消息队列(如 Redis、RabbitMQ、AWS SQS)中那些无法被正常消费的消息。
你问的 DLX(Dead Letter Exchange) 和 DLQ(Dead Letter Queue) 其实是同一个东西的两种不同叫法:
- DLQ(Dead Letter Queue):是通用术语,意思就是“死信队列”,用于存储那些消费失败、被拒绝或过期的消息。
- DLX(Dead Letter Exchange):是 RabbitMQ 特有的概念,表示当消息变成死信时,它会被重新投递到指定的交换机(Exchange),然后路由到对应的死信队列(DLQ)。
- 如果你用的是 RabbitMQ,可以配置 DLX(Dead Letter Exchange)来实现死信处理。
- 如果你用的是 Redis 或 AWS SQS,它们没有 DLX 的概念,但仍然可以模拟 DLQ 行为。
在 Laravel 中的实践建议
如果你在 Laravel 中使用 RabbitMQ(配合 vladimir-yuldashev/laravel-queue-rabbitmq)
RabbitMQ 原生支持 DLX,你可以在队列配置中指定:
// config/queue.php
'rabbitmq' => [
'driver' => 'rabbitmq',
'queue' => 'default',
'hosts' => [
[
'host' => env('RABBITMQ_HOST', '127.0.0.1'),
'port' => env('RABBITMQ_PORT', 5672),
],
],
'options' => [
'queue' => [
'exchange' => 'laravel_exchange',
'exchange_type' => 'direct',
'binding' => 'laravel_queue',
'arguments' => [
'x-dead-letter-exchange' => 'laravel_dead_letter_exchange', // DLX 指定
'x-dead-letter-routing-key' => 'dead_letter_queue',
],
],
// ...
],
],
这样当消息被拒绝、nack、过期或超过最大重试次数后,会自动进入 dead_letter_queue。
如果你用的是 Redis 队列(Laravel 默认)
Redis 队列没有 DLX 概念,但你可以手动模拟 DLQ:
- 使用 Laravel 自带的 failed_jobs 表(默认迁移已经提供)。
- 或者在任务中捕获异常,手动将消息发布到另一个专门的死信队列:
public function handle()
{
try {
// 业务逻辑
} catch (\Exception $e) {
// 手动投递到死信队列
dispatch(new DeadLetterJob($this->data))->onQueue('dead_letter');
// 或者记录到 failed_jobs 表
throw $e; // 让 Laravel 自动处理失败
}
}
Redis 下更推荐的做法是:
- 配置 Laravel 的
failed_jobs表并定期查看、重试。 - 或者安装
laravel/horizon来可视化管理和监控超时、失败任务。
如果你用的是 Amazon SQS
SQS 原生支持 DLQ(Redrive Policy),你可以在 SQS 控制台配置:
- 创建主队列时,指定一个“死信队列”ARN
- 设置
maxReceiveCount(3),如果消息被接收 3 次后仍未删除,自动转入 DLQ
在 Laravel 中你不需要改代码,只需在 AWS 控制台配置好 SQS 的主队列与 DLQ 关联,然后直接在 config/queue.php 里正常使用主队列即可:
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'queue' => env('SQS_QUEUE_URL'), // 主队列 URL
'region' => env('AWS_DEFAULT_REGION'),
],
最终建议
| 你的队列驱动 | 技术方案 | 推荐做法 |
|---|---|---|
| RabbitMQ | 使用 DLX | 在配置中设置 x-dead-letter-exchange 和 x-dead-letter-routing-key |
| Redis | 没有原生 DLX | 使用 failed_jobs 表或手动投递到死信队列 |
| Amazon SQS | 原生 DLQ | 在 AWS 控制台配置 Redrive Policy,Laravel 正常使用主队列 |
一句话总结:
- 如果你用 RabbitMQ → 用 DLX(RabbitMQ 专有名词)
- 如果你用 Redis 或 SQS → 用 DLQ(通用概念)
- 本质上它们的作用相同:把处理不了的消息隔离到另一个队列,便于排查和重试。