rabbitmq实现延迟队列

rabbitmq实现延迟队列

延迟队列串存储的对象是对应的延迟消息。rabbitmq本身没有支持延迟队列的功能,通过DLX(死信队列)+TTL消息模拟延迟队列

延迟消息是指消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到消息并消费

延迟队列场景

  • 订单系统中,如果用户下单30分钟内没有进行支付,就需要自动将这些订单设置为失效
  • 支付结果通知,为1分钟,5分钟,10分钟…的通知

示例

场景描述

设置了5s,10s,30s三个等级的通知队列,同时为这些队列设置了DLX各DLX相对应的死信队列。当相应的消息过期时,就会转到相应对的延迟队列(死信队列)

延迟队列实现图

延迟队列示例图:
在这里插入图片描述

代码实现
public class DelayedQueueSender {


    private static final String EX_NORMAL = "EX_NORMAL";
    private static final String EX_DLX_5S = "EX_DLX_5S";
    private static final String EX_DLX_10S = "EX_DLX_10S";
    private static final String EX_DLX_30S = "EX_DLX_30S";

    private static final String Q_NORMAL_5S = "Q_NORMAL_5S";
    private static final String Q_NORMAL_10S = "Q_NORMAL_10S";
    private static final String Q_NORMAL_30S = "Q_NORMAL_30S";
    private static final String Q_DLX_5S = "Q_DLX_5S";
    private static final String Q_DLX_10S = "Q_DLX_10S";
    private static final String Q_DLX_30S = "Q_DLX_30S";

    private static final String RT_NORMAL = "RT_NORMAL";
    private static final String RT_DLX_5S = "RT_DLX_5S";
    private static final String RT_DLX_10S = "RT_DLX_10S";
    private static final String RT_DLX_30S = "RT_DLX_30S";


    public static void main(String[] args) throws IOException, TimeoutException {


        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EX_NORMAL, BuiltinExchangeType.FANOUT);
        channel.exchangeDeclare(EX_DLX_5S, BuiltinExchangeType.DIRECT);
        channel.exchangeDeclare(EX_DLX_10S, BuiltinExchangeType.DIRECT);
        channel.exchangeDeclare(EX_DLX_30S, BuiltinExchangeType.DIRECT);

        Map<String, Object> map5s = new HashMap<>();
        map5s.put("x-message-ttl", 5000);
        map5s.put("x-dead-letter-exchange", EX_DLX_5S);
        map5s.put("x-dead-letter-routing-key", RT_DLX_5S);
        channel.queueDeclare(Q_NORMAL_5S, true, false, false, map5s);
        channel.queueBind(Q_NORMAL_5S, EX_NORMAL, "");

        Map<String, Object> map10s = new HashMap<>();
        map10s.put("x-message-ttl", 10000);
        map10s.put("x-dead-letter-exchange", EX_DLX_10S);
        map10s.put("x-dead-letter-routing-key", RT_DLX_10S);
        channel.queueDeclare(Q_NORMAL_10S, true, false, false, map10s);
        channel.queueBind(Q_NORMAL_10S, EX_NORMAL, "");

        Map<String, Object> map30s = new HashMap<>();
        map30s.put("x-message-ttl", 30000);
        map30s.put("x-dead-letter-exchange", EX_DLX_30S);
        map30s.put("x-dead-letter-routing-key", RT_DLX_30S);
        channel.queueDeclare(Q_NORMAL_30S, true, false, false, map30s);
        channel.queueBind(Q_NORMAL_30S, EX_NORMAL, "");


        //死信队列
        channel.queueDeclare(Q_DLX_5S, true, false, false, null);
        channel.queueBind(Q_DLX_5S, EX_DLX_5S, RT_DLX_5S);

        channel.queueDeclare(Q_DLX_10S, true, false, false, null);
        channel.queueBind(Q_DLX_10S, EX_DLX_10S, RT_DLX_10S);

        channel.queueDeclare(Q_DLX_30S, true, false, false, null);
        channel.queueBind(Q_DLX_30S, EX_DLX_30S, RT_DLX_30S);

        channel.basicPublish(EX_NORMAL, RT_NORMAL, null, "5s_hello".getBytes());
        System.out.println("send msg...");

    }

}

从Web管理页面看:

消息示过期前先发送到normal队列:
在这里插入图片描述
10s之后:
在这里插入图片描述

消息过期后发送到延迟队列:

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值