使用 RabbitMQ 实现延时发送的几种方法

方法一:利用 TTL 和 DLX(死信队列)

RabbitMQ 本身不支持直接的延时队列,但可以通过 TTL(Time-To-Live)和 DLX(Dead Letter Exchange)组合实现延时效果。

  1. 创建普通队列并设置 TTL,绑定到业务交换机。
  2. 为队列配置死信交换机(DLX)和死信路由键。
  3. 消息过期后,自动转发到死信队列,由消费者处理。

示例代码:

// 声明死信交换机和队列
channel.exchangeDeclare("dlx.exchange", "direct");
channel.queueDeclare("dlx.queue", true, false, false, null);
channel.queueBind("dlx.queue", "dlx.exchange", "dlx.routing.key");

// 声明业务队列并设置 TTL 和 DLX
Map<String, Object> args = new HashMap<>();
args.put("x-message-ttl", 10000); // TTL 10秒
args.put("x-dead-letter-exchange", "dlx.exchange");
args.put("x-dead-letter-routing-key", "dlx.routing.key");
channel.queueDeclare("delay.queue", true, false, false, args);

方法二:使用 RabbitMQ 插件(rabbitmq_delayed_message_exchange)

RabbitMQ 3.5.8 及以上版本支持官方延时插件,需手动安装。

  1. 下载插件并启用:
    rabbitmq-plugins enable rabbitmq_delayed_message_exchange
    

  2. 声明自定义交换机类型为 x-delayed-message,并设置路由方式(如 direct)。

示例代码:

Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
channel.exchangeDeclare("delayed.exchange", "x-delayed-message", true, false, args);
channel.queueDeclare("delayed.queue", true, false, false, null);
channel.queueBind("delayed.queue", "delayed.exchange", "delayed.key");

// 发送延时消息
Map<String, Object> headers = new HashMap<>();
headers.put("x-delay", 5000); // 延时5秒
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
    .headers(headers)
    .build();
channel.basicPublish("delayed.exchange", "delayed.key", props, message.getBytes());

方法三:外部定时任务 + 消息存储

适用于高精度延时需求,但实现复杂度较高。

  1. 将延时消息存储到数据库(如 MySQL),记录目标发送时间。
  2. 通过定时任务(如 Spring Scheduler)扫描到期消息。
  3. 将消息投递到 RabbitMQ 普通队列。

示例代码片段:

@Scheduled(fixedDelay = 1000)
public void scanDelayedMessages() {
    List<Message> messages = repository.findBySendTimeBefore(new Date());
    messages.forEach(msg -> {
        rabbitTemplate.convertAndSend("target.exchange", "target.key", msg);
        repository.delete(msg);
    });
}

注意事项
  • TTL+DLX 缺点:队列中消息过期时间是固定的,若动态调整需为每条消息设置单独 TTL(可能影响性能)。
  • 插件优点:支持动态延时,但需确保插件兼容性和集群配置一致性。
  • 定时任务缺点:依赖外部存储,可能引入一致性问题(如任务失败需补偿)。

选择方法时需根据业务场景权衡实现复杂度和延时精度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值