在电商系统或其他业务系统中,订单超时未支付处理 、定时任务调度 是非常常见的需求。如果处理不当,容易出现库存锁定、数据不一致或者任务延迟等问题。
本文将用 C# 搭配 RabbitMQ 的延迟队列功能,给你一个完整的实战方案,让你落地即用。
一、为什么选择 RabbitMQ 延迟队列
延迟队列的作用是将消息延迟一段时间再消费,非常适合以下场景:
-
订单超时未支付,自动取消订单
-
定时任务调度,例如定时发送提醒或报告
-
秒杀或抢购活动中的延时消息处理
传统做法可能是用数据库轮询或者 Timer,效率低且扩展性差,而 RabbitMQ 延迟队列能轻松应对高并发场景,并保证消息可靠投递。
二、RabbitMQ 延迟队列实现原理
RabbitMQ 自身不直接支持消息延迟,但可以通过 TTL(消息过期时间) + 死信队列(DLX) 实现。原理如下:
-
消息发送到 延迟队列,设置 TTL(例如 30 分钟)
-
TTL 到期后,消息被转发到 死信队列
-
消费者监听 死信队列,进行实际处理(如取消订单)
示意图:
生产者 --> 延迟队列(30分钟TTL) --> 死信队列 --> 消费者处理
三、C# 环境准备
-
安装 RabbitMQ
-
官方文档:RabbitMQ 官方网站
-
启用管理插件:
rabbitmq-plugins enable rabbitmq_management
-
-
安装 .NET RabbitMQ 客户端:
dotnet add package RabbitMQ.Client
四、创建延迟队列与死信队列
using RabbitMQ.Client;
using System;
using System.Text;
class Program
{
static void Main()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
// 死信队列
channel.QueueDeclare(
queue: "order.deadletter.queue",
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
// 延迟队列,设置死信队列和TTL
var args = new Dictionary<string, object>
{
{"x-dead-letter-exchange", ""}, // 默认交换机
{"x-dead-letter-routing-key", "order.deadletter.queue"},
{"x-message-ttl", 30 * 60 * 1000} // 30分钟
};
channel.QueueDeclare(
queue: "order.delay.queue",
durable: true,
exclusive: false,
autoDelete: false,
arguments: args);
Console.WriteLine("队列创建完成。");
}
}
说明:
-
x-message-ttl:消息存活时间(毫秒) -
x-dead-letter-exchange+x-dead-letter-routing-key:TTL 到期后转发到死信队列
五、生产者发送延迟消息
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
var body = Encoding.UTF8.GetBytes("订单12345未支付,自动取消");
var properties = channel.CreateBasicProperties();
properties.Persistent = true;
channel.BasicPublish(
exchange: "",
routingKey: "order.delay.queue",
basicProperties: properties,
body: body);
Console.WriteLine("延迟消息发送成功");
六、消费者监听死信队列处理消息
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
var consumer = new RabbitMQ.Client.Events.EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var message = Encoding.UTF8.GetString(ea.Body.ToArray());
Console.WriteLine($"处理超时订单: {message}");
// TODO: 执行取消订单或其他业务逻辑
};
channel.BasicConsume(
queue: "order.deadletter.queue",
autoAck: true,
consumer: consumer);
Console.WriteLine("等待死信队列消息...");
Console.ReadLine();
七、实战优化建议
-
多种延迟策略
-
短延迟:几秒~几分钟,用 TTL + 死信队列即可
-
长延迟:几小时~几天,考虑分级延迟队列或结合数据库记录
-
-
幂等处理
- 消费者执行操作前检查订单状态,避免重复取消
-
高可用部署
- RabbitMQ 集群 + 持久化队列保证消息可靠性
八、总结
通过本文,你可以用 C# + RabbitMQ 延迟队列 实现:
-
订单超时自动取消
-
定时任务调度
-
高并发环境下的可靠消息处理
只需配置 TTL 和死信队列,就能快速落地,并保证业务可靠性。
这个方案非常适合电商系统、秒杀活动以及其他需要延迟处理的场景。