前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >RabbitMQ之死信队列(实战篇)

RabbitMQ之死信队列(实战篇)

作者头像
小熊学Java
发布于 2023-07-16 06:32:56
发布于 2023-07-16 06:32:56
61200
代码可运行
举报
文章被收录于专栏:全栈学习之路全栈学习之路
运行总次数:0
代码可运行

1、概念

先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer 将消息投递到 broker 或者直接到 queue 里了,consumer 从 queue 取出消息进行消费,但某些时候由于特定的原因导致 queue 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。 **应用场景:**为了保证订单业务的消息数据不丢失,需要使用到 RabbitMQ 的死信队列机制,当消息消费发生异常时,将消息投入死信队列中;还有比如说: 用户在商城下单成功并点击去支付后在指定时间未支付时自动失效

2、死信的来源

  • 消息 TTL 过期
  • 队列达到最大长度(队列满了,无法再添加数据到 mq 中)
  • 消息被拒绝(basic.reject 或 basic.nack)并且 requeue=false.

3、实战

1、代码架构图

流程说明:

  1. 一个生产者,两个消费者,交换机为直接类型
  2. 正常流程:生产者发送消息,经过正常队列后,由 C1 进行消费
  3. 产生三大问题后的流程:生产者发送消息,经过正常队列,由于出现了三大问题,C1没有接收到消息,不能进行消费,需转发到死信交换机中的队列里,由C2进行消费。

实现说明:

  • 由于C1未进行消费,需转发到C2,所以C1消费者需创建两个交换机和队列
  • C2只需进行正常消费死信队列的消息即可

2、消息 TTL 过期

1、场景模拟

  1. 先启动消费者C1,创建好交换机和队列
  2. 关闭C1,然后启动生产者和消费者C2
  3. 因C1被关闭,所以生产者发送的消息无法被消费,过了时间后,会进入死信队列,被C2进行消费
2、消费者01
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Consumer01 {

    /**
     * 正常交换机
     */
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    /**
     * 死信交换机
     */
    public static final String DEAD_EXCHANGE = "dead_exchange";

    //正常队列
    public static final String NORMAL_QUEUE = "normal_queue";
    //死信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        //声明交换机
        channel.exchangeDeclare(NORMAL_EXCHANGE, BuiltinExchangeType.DIRECT);
        channel.exchangeDeclare(DEAD_EXCHANGE, BuiltinExchangeType.DIRECT);

        //正常队列绑定死信队列信息
        Map<String, Object> params = new HashMap<>();
        //设置过期时间
//        params.put("x-message-ttl", 10000);
        //正常队列设置死信交换机 参数 key 是固定值
        params.put("x-dead-letter-exchange", DEAD_EXCHANGE);
        //正常队列设置死信 routing-key 参数 key 是固定值
        params.put("x-dead-letter-routing-key", "dead");
        channel.queueDeclare(NORMAL_QUEUE, false, false, false, params);
        //声明队列 不共享 不持久化 不删除
        channel.queueDeclare(DEAD_QUEUE, false, false, false, null);

        //绑定交换机和队列
        channel.queueBind(NORMAL_QUEUE, NORMAL_EXCHANGE, "normal");
        channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "dead");
        System.out.println("等待接收消息......");
        DeliverCallback deliverCallback =  (consumerTag, deliver) ->{
            //获取消息
            String message = new String(deliver.getBody(), "UTF-8");
            System.out.println("Consumer01接收到的消息为:" + message);
        };
        channel.basicConsume(NORMAL_QUEUE, true, deliverCallback, cancelCallback -> {});
    }
}
3、消费者02
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Consumer02 {

    /**
     * 死信交换机
     */
    public static final String DEAD_EXCHANGE = "dead_exchange";


    //死信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        //声明交换机
        channel.exchangeDeclare(DEAD_EXCHANGE, BuiltinExchangeType.DIRECT);
        //声明队列 不共享 不持久化 不删除
        channel.queueDeclare(DEAD_QUEUE, false, false, false, null);

        //绑定交换机和队列
        channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "dead");
        System.out.println("等待接收消息......");
        DeliverCallback deliverCallback =  (consumerTag, deliver) ->{
            //获取消息
            String message = new String(deliver.getBody(), "UTF-8");
            System.out.println("Consumer02接收到的消息为:" + message);
        };
        channel.basicConsume(DEAD_QUEUE, true, deliverCallback, cancelCallback -> {});
    }
}
4、生产者
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Product {
    /**
     * 正常交换机
     */
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    //正常队列
    public static final String NORMAL_QUEUE = "normal_queue";


    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        //设置消息的 TTL 时间
        AMQP.BasicProperties properties = new
                AMQP.BasicProperties().builder().expiration("10000").build();

        for (int i = 1; i < 11; i++) {
            String msg = "消息" + i;
            channel.basicPublish(NORMAL_EXCHANGE, "normal", properties, msg.getBytes(StandardCharsets.UTF_8));
        }
    }
}
5、监控图对比
  • 启动生产者,关闭消费者C1,未启动消费者C2
  • 启动生产者,关闭消费者C1,未启动消费者C2,时间经过10s后
  • 启动生产者,关闭消费者C1,启动消费者C2
6、设置过期时间
1、生产者设置

生产者设置具有灵活性,第一条消息可设置10s,第二条设置8s

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//设置消息的 TTL 时间
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().expiration("10000").build();
2、消费者设置

消费者设置,所有消息的ttl都是一样的,没有灵活性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//正常队列绑定死信队列信息
Map<String, Object> params = new HashMap<>();
//设置过期时间
params.put("x-message-ttl", 10000);

//正常队列设置死信交换机 参数 key 是固定值
params.put("x-dead-letter-exchange", DEAD_EXCHANGE);
//正常队列设置死信 routing-key 参数 key 是固定值
params.put("x-dead-letter-routing-key", "dead");
channel.queueDeclare(NORMAL_QUEUE, false, false, false, params);

3、队列达到最大长度

消息达到设置的最大长度后,多与的消息会进入死信队列

1、场景模拟

  1. 先启动消费者C1,创建好交换机和队列
  2. 关闭C1,然后启动生产者和消费者C2
  3. C1设置的队列最大长度为6,多与的消息会进入死信队列,被C2消费
  4. 再启动C1,C1消费6条
2、生产者
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Product {
    /**
     * 正常交换机
     */
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        for (int i = 1; i < 11; i++) {
            String msg = "消息" + i;
            channel.basicPublish(NORMAL_EXCHANGE, "normal", properties, msg.getBytes(StandardCharsets.UTF_8));
        }
    }
}
3、消费者01
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Consumer01 {

    /**
     * 正常交换机
     */
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    /**
     * 死信交换机
     */
    public static final String DEAD_EXCHANGE = "dead_exchange";

    //正常队列
    public static final String NORMAL_QUEUE = "normal_queue";
    //死信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        //声明交换机
        channel.exchangeDeclare(NORMAL_EXCHANGE, BuiltinExchangeType.DIRECT);
        channel.exchangeDeclare(DEAD_EXCHANGE, BuiltinExchangeType.DIRECT);

        //正常队列绑定死信队列信息
        Map<String, Object> params = new HashMap<>();
        //设置过期时间
//        params.put("x-message-ttl", 10000);
        //设置队列长度的限制
        params.put("x-max-length", 6);
        //正常队列设置死信交换机 参数 key 是固定值
        params.put("x-dead-letter-exchange", DEAD_EXCHANGE);
        //正常队列设置死信 routing-key 参数 key 是固定值
        params.put("x-dead-letter-routing-key", "dead");
        channel.queueDeclare(NORMAL_QUEUE, false, false, false, params);
        //声明队列 不共享 不持久化 不删除
        channel.queueDeclare(DEAD_QUEUE, false, false, false, null);

        //绑定交换机和队列
        channel.queueBind(NORMAL_QUEUE, NORMAL_EXCHANGE, "normal");
        channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "dead");
        System.out.println("等待接收消息......");
        DeliverCallback deliverCallback =  (consumerTag, deliver) ->{
            //获取消息
            String message = new String(deliver.getBody(), "UTF-8");
            System.out.println("Consumer01接收到的消息为:" + message);
        };
        channel.basicConsume(NORMAL_QUEUE, true, deliverCallback, cancelCallback -> {});
    }
}
4、消费者02
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Consumer02 {

    /**
     * 死信交换机
     */
    public static final String DEAD_EXCHANGE = "dead_exchange";


    //死信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        //声明交换机
        channel.exchangeDeclare(DEAD_EXCHANGE, BuiltinExchangeType.DIRECT);
        //声明队列 不共享 不持久化 不删除
        channel.queueDeclare(DEAD_QUEUE, false, false, false, null);

        //绑定交换机和队列
        channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "dead");
        System.out.println("等待接收消息......");
        DeliverCallback deliverCallback =  (consumerTag, deliver) ->{
            //获取消息
            String message = new String(deliver.getBody(), "UTF-8");
            System.out.println("Consumer02接收到的消息为:" + message);
        };
        channel.basicConsume(DEAD_QUEUE, true, deliverCallback, cancelCallback -> {});
    }
}
5、监控图对比
  • C1启动时,其他未启动
  • 启动生产者,关闭消费者,未启动C2
  • 启动C2
  • 启动C1
6、设置队列最大长度
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//正常队列绑定死信队列信息
Map<String, Object> params = new HashMap<>();
//设置队列长度的限制
params.put("x-max-length", 6);
//正常队列设置死信交换机 参数 key 是固定值
params.put("x-dead-letter-exchange", DEAD_EXCHANGE);
//正常队列设置死信 routing-key 参数 key 是固定值
params.put("x-dead-letter-routing-key", "dead");
channel.queueDeclare(NORMAL_QUEUE, false, false, false, params);

4、消息被拒绝

1、场景模拟

  1. 先启动消费者C1,创建好交换机和队列
  2. 然后启动生产者和消费者C2
  3. C1设置的队列拒绝接收消息“消息6”
  4. “消息6”被C2消费
2、生产者
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Product {
    /**
     * 正常交换机
     */
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        for (int i = 1; i < 11; i++) {
            String msg = "消息" + i;
            channel.basicPublish(NORMAL_EXCHANGE, "normal", properties, msg.getBytes(StandardCharsets.UTF_8));
        }
    }
}
3、消费者01
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Consumer01 {

    /**
     * 正常交换机
     */
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    /**
     * 死信交换机
     */
    public static final String DEAD_EXCHANGE = "dead_exchange";

    //正常队列
    public static final String NORMAL_QUEUE = "normal_queue";
    //死信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        //声明交换机
        channel.exchangeDeclare(NORMAL_EXCHANGE, BuiltinExchangeType.DIRECT);
        channel.exchangeDeclare(DEAD_EXCHANGE, BuiltinExchangeType.DIRECT);

        //正常队列绑定死信队列信息
        Map<String, Object> params = new HashMap<>();
        //正常队列设置死信交换机 参数 key 是固定值
        params.put("x-dead-letter-exchange", DEAD_EXCHANGE);
        //正常队列设置死信 routing-key 参数 key 是固定值
        params.put("x-dead-letter-routing-key", "dead");
        channel.queueDeclare(NORMAL_QUEUE, false, false, false, params);
        //声明队列 不共享 不持久化 不删除
        channel.queueDeclare(DEAD_QUEUE, false, false, false, null);

        //绑定交换机和队列
        channel.queueBind(NORMAL_QUEUE, NORMAL_EXCHANGE, "normal");
        channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "dead");
        System.out.println("等待接收消息......");
        DeliverCallback deliverCallback =  (consumerTag, deliver) ->{
            //获取消息
            String message = new String(deliver.getBody(), "UTF-8");
            if ("消息6".equals(message)){
                System.out.println("Consumer01 接收到消息" + message + "并拒绝签收该消息");
                //requeue 设置为 false 代表拒绝重新入队 该队列如果配置了死信交换机将发送到死信队列中
                channel.basicReject(deliver.getEnvelope().getDeliveryTag(), false);
            }else {
                System.out.println("Consumer01 接收到消息"+message);
                channel.basicAck(deliver.getEnvelope().getDeliveryTag(), false);
            }
        };
        //
        channel.basicConsume(NORMAL_QUEUE, false, deliverCallback, cancelCallback -> {});
    }
}
4、消费者02
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Consumer02 {

    /**
     * 死信交换机
     */
    public static final String DEAD_EXCHANGE = "dead_exchange";

    //死信队列
    public static final String DEAD_QUEUE = "dead_queue";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQConfig.getChannel();
        //声明交换机
        channel.exchangeDeclare(DEAD_EXCHANGE, BuiltinExchangeType.DIRECT);
        //声明队列 不共享 不持久化 不删除
        channel.queueDeclare(DEAD_QUEUE, false, false, false, null);

        //绑定交换机和队列
        channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "dead");
        System.out.println("等待接收消息......");
        DeliverCallback deliverCallback =  (consumerTag, deliver) ->{
            //获取消息
            String message = new String(deliver.getBody(), "UTF-8");
            System.out.println("Consumer02接收到的消息为:" + message);
        };
        channel.basicConsume(DEAD_QUEUE, true, deliverCallback, cancelCallback -> {});
    }
}
5、监控图对比
  • 其他均启动,C2未启动时
6、设置消息被拒绝
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//获取消息
String message = new String(deliver.getBody(), "UTF-8");
if ("消息6".equals(message)){
    System.out.println("Consumer01 接收到消息" + message + "并拒绝签收该消息");
    //requeue 设置为 false 代表拒绝重新入队 该队列如果配置了死信交换机将发送到死信队列中
    channel.basicReject(deliver.getEnvelope().getDeliveryTag(), false);
}else {
    System.out.println("Consumer01 接收到消息"+message);
    channel.basicAck(deliver.getEnvelope().getDeliveryTag(), false);
}
//消费成功之后是否要自动应答 true 代表自动应答 false 手动应答
channel.basicConsume(NORMAL_QUEUE, false, deliverCallback, cancelCallback -> {});

如果觉得内容不错的话,希望大家可以帮忙点赞转发一波,这是对我最大的鼓励,感谢🙏🏻

END

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小熊学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
死信队列 和消息TTL过期代码
先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer将消息投递到broker或者直接到queue里了,consumer从queue取出消息进行消费,但某些时候由于特定的原因导致queue中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。
一个风轻云淡
2022/11/13
3120
死信队列 和消息TTL过期代码
RabbitMQ之死信队列
概念 先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer 将消息投递到 broker 或者直接到queue 里了,consumer 从 queue 取出消息 进行消费,但某些时候由于特定的原因导致 queue 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。 应用场景:为了保证订单业务的消息数据不丢失,需要使用到 RabbitMQ 的死信队列机制,当消息消费发生异常时,将消息投入死信队列中。还有
shaoshaossm
2022/12/27
2600
RabbitMQ之死信队列
RabbitMQ 死信队列
先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer 将消息投递到 broker 或者直接到queue 里了,consumer 从 queue 取出消息 进行消费,但某些时候由于特定的原因导致 queue 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。
用户9615083
2022/12/25
3920
RabbitMQ 死信队列
RibbitMQ学习笔记之死信队列
先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer 将消息投递到 broker 或者直接到queue 里了,consumer 从 queue 取出消息进行消费,但某些时候由于特定的原因导致 queue 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。
默 语
2024/11/20
1030
RibbitMQ学习笔记之死信队列
爆肝3万字,为你吃透RabbitMQ,最详细的RabbitMQ讲解(VIP典藏版)
早在之前就了解到了消息中间件,但是一直没有系统的学习,最近花了一段时间系统学习了当下最为主流的 RabbitMQ 消息队列,学习过程中也随时记录,刚开始学习的时候懵懵懂懂,做的笔记都比较杂乱,系统学习完后我将笔记内容不断反复修改,对章节进行设计调整,最终整合出了以下好理解、案例多、超详细的 RabbitMQ 学习笔记,希望能帮到大家~
SmallRoll小卷
2023/03/05
12.6K0
爆肝3万字,为你吃透RabbitMQ,最详细的RabbitMQ讲解(VIP典藏版)
RabbitMQ 如何实现延迟队列?答案可不止一种
RabbitMQ 本身不支持延迟消息,但是可以通过它提供的两个特性 TTL(Time-To-Live and Expiration ,消息存活时间)、DLX(Dead Letter Exchanges,死信交换器) 来实现。还可以利用 RabbitMQ 插件来实现。
程序员鱼皮
2024/08/20
6640
RabbitMQ 如何实现延迟队列?答案可不止一种
SpringBoot整合RabbitMQ实现死信队列
前面一文Java整合RabbitMQ实现生产消费(7种通讯方式),本文基于SpringBoot实现RabbitMQ中的死信队列和延迟队列。
王二蛋
2024/02/08
5670
RabbitMQ---消息队列---上半部分
MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是message 而已,还是一种跨进程的通信机制,用于上下游传递消息。在互联网架构中,MQ 是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了 MQ 之后,消息发送上游只需要依赖 MQ,不用依赖其他服务。
大忽悠爱学习
2021/12/07
1.1K0
RabbitMQ---消息队列---上半部分
RabbitMQ
​ MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是 message 而已,还是一种跨进程的通信机制,用于上下游传递消息。在互联网架构中,MQ 是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了 MQ 之后,消息发送上游只需要依赖 MQ,不用依赖其他服务。
OY
2022/03/21
1.8K0
RabbitMQ
RabbitMQ的死信队列
RabbitMQ的死信队列(Dead Letter Queue,简称DLQ)是一种用于处理消息失败或无法路由的消息的机制。在RabbitMQ中,当消息出现以下情况时,它可能会被标记为死信:
会洗碗的CV工程师
2024/05/03
1.3K0
RabbitMQ的死信队列
RabbitMQ 死信队列
死信队列是指队列上的消息变成死信后,能够后发送到另外一个交换机,这个交换机 就是 DLX 。
王小明_HIT
2019/08/27
8090
RabbitMQ 死信队列
消息被拒MQ
生产者 /** * 消息被拒的情况 */ public class Produce0001 { private static final String NORMAL_EXCHANGE="normal_exchange"; public static void main(String[] args) throws Exception{ Channel channel = untils.getChannel(); channel.exchangeDe
一个风轻云淡
2022/11/13
4000
消息被拒MQ
RibbitMQ学习笔记之交换机实战
在上一节中,我们创建了一个工作队列。我们假设的是工作队列背后,每个任务都恰好交付给一个消费者(工作进程)。在这一部分中,我们将做一些完全不同的事情-我们将消息传达给多个消费者。这种模式称为 ”发布/订阅”.
默 语
2024/11/20
790
RibbitMQ学习笔记之交换机实战
高性能消息队列中间件MQ_part2
之前我们使用原生JAVA操作RabbitMQ较为繁琐,接下来我们使用SpringBoot整合RabbitMQ,简化代码编写。
天天Lotay
2023/02/16
4620
高性能消息队列中间件MQ_part2
队列达到最大长度代码实战
生产者001 /** * 队列到达最大长度的情况 */ public class Producer001 { private static final String NORMAL_EXCHANGE="normal_exchange"; public static void main(String[] args) throws Exception{ Channel channel = untils.getChannel(); channel.ex
一个风轻云淡
2022/11/13
1.2K0
队列达到最大长度代码实战
03、RabbitMQ延迟队列(死信交换机)
天蝎座的程序媛
2023/10/17
2970
03、RabbitMQ延迟队列(死信交换机)
RabbitMQ没有延时队列?我就教你一招,玩转延时队列
延时队列:顾名思义,是一个用于做消息延时消费的队列。但是它也是一个普通队列,所以它具备普通队列的特性,相比之下,延时的特性就是它最大的特点。所谓的延时就是将我们需要的消息,延迟多久之后被消费。普通队列是即时消费的,延时队列是根据延时时间,多久之后才能消费的。
Java程序猿阿谷
2021/03/05
8500
RabbitMQ没有延时队列?我就教你一招,玩转延时队列
RabbitMQ 超详细入门篇
本人使用的是 阿里云服务器 没有的话也可以使用虚拟机… 事先使用连接工具上传了文件
Java_慈祥
2024/08/06
2.7K0
RabbitMQ 超详细入门篇
消息队列RabbitMQ核心:交换机(路由、主题、发布订阅)
在上一篇的学习中,使用创建了一个工作队列,我们假设的是工作队列背后,每个任务都恰好交给一个消费者(工作进程)。之前都是将消息发送到队列中,然后由消费者进行消费,其实在RabbitMQ有一个默认的交换机,在发消息时无需指定交换机。
百思不得小赵
2022/12/20
9430
消息队列RabbitMQ核心:交换机(路由、主题、发布订阅)
死信队列
/** * @Auther: Administrator * @Date: 2019年7月16日 * @Description: 死信交换机 生产者首先发送一条携带路由键为 " dlx " 的消息,然后经过交换器 * exchange .normal 顺利地存储到队列 queue.normal 中 。由于队列 queue.normal 设置了过期时间为 * 10s , 在这 10s 内没有消费者消费这条消息,那么判定这条消息为过期。由于设置了 DLX , 过期 * 之时 , 消息被丢给交换
清风冷影
2019/07/16
4610
相关推荐
死信队列 和消息TTL过期代码
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验