zoukankan      html  css  js  c++  java
  • rabbitMq消息持久化机制,和延时队列

    1、RabbitMQ的一大特色是消息的可靠性,那么它是如何保证消息可靠性的呢?

    消息持久化。可以将Queue,Exchange,Message都设置为可持久化的。为了保证RabbitMQ在退出,服务重启或者crash等异常情况下,也不会丢失消息。

    2、RabbitMQ服务异常,重启时候怎么保证消息不丢失,持久化的实现?

    1、Queue(消息队列)的持久化是通过durable=true来实现的。 

    Connection connection = connectionFactory.newConnection();
    Channel channel = connection.createChannel();
    //关键的是第二个参数设置为true,即durable=true.
    channel.queueDeclare("queue.persistent.name", true, false, false, null);
    /到这步仅仅是做到了消息队列的持久化,还没有做消息持久化。

    2、Message(消息)的持久化 ,通过设置消息是持久化的标识。

    //MessageProperties.PERSISTENT_TEXT_PLAIN 
    channel.basicPublish("exchange.persistent", "persistent", MessageProperties.PERSISTENT_TEXT_PLAIN, "persistent_test_message".getBytes());

    3、Exchange(交换机)的持久化 。

    //即在声明的时候讲durable字段设置为true即可。
    channel.exchangeDeclare(exchangeName, “direct/topic/header/fanout”, true);

    3、死信队列是什么?

    1、死信队列是一个普通的队列,它没有消费者,用来存储有超时时间信息的消息,并且可以设置当消息超时(ttl),等待消息超时,将消息转发到指定的Router队列。

    2、“死信”是RabbitMQ中的一种消息机制,当你在消费消息时,如果队列里的消息出现以下情况:

    1. 消息被否定确认,使用 channel.basicNack 或 channel.basicReject ,并且此时requeue 属性被设置为false
    2. 消息在队列的存活时间超过设置的TTL时间。
    3. 消息队列的消息数量已经超过最大队列长度。

    “死信”消息会被RabbitMQ进行特殊处理,如果配置了死信队列信息,那么该消息将会被丢进死信队列中,如果没有配置,则该消息将会被丢弃。

    3、延时队列和转发队列是什么?

    延时队列:就是用来存放需要在指定时间被处理的元素的队列。

    转发队列:用来接收死信队列超时消息,在接收到之后,消费者将消息解析,获取queueName,body,再向所获取的queueName队列发送一条消息,内容为body。

    分析:首先rabbitmq自己是不具备延时的功能的,除了使用官方提供的插件之外,我们还可以通过TTL(设置超时时间的方式)+ DLX(一个死信队列) + Router(转发队列)来实现。

    4、怎么设置消息超时时间ttl?

      TTLTTL是RabbitMQ中一个消息或者队列的属性,表明一条消息或者该队列中的所有消息的最大存活时间,单位是毫秒。如果一条消息设置了TTL属性或者进入了设置TTL属性的队列,那么这条消息如果在TTL设置的时间内没有被消费,则会成为“死信”。

    1、设置在队列上:如果设置了队列的TTL属性,那么一旦消息过期,就会被队列丢弃。

    2、ttl可以设置在消息上:消息即使过期,也不一定会被马上丢弃,因为消息是否过期是在即将投递到消费者之前判定的,如果当前队列有严重的消息积压情况,则已过期的消息也许还能存活较长时间。

    设置这个TTL值呢?有两种方式,2种是在创建队列的时候设置队列的“x-message-ttl”属性,如下:

    //第一种这样所有被投递到该队列的消息都最多不会存活超过6s。
    Map<String, Object> args = new HashMap<String, Object>();
    args.put("x-message-ttl", 6000);
    channel.queueDeclare(queueName, durable, exclusive, autoDelete, args);
    //第二种针对每条消息设置TTL
    AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
    builder.expiration("6000");
    AMQP.BasicProperties properties = builder.build();
    channel.basicPublish(exchangeName, routingKey, mandatory, properties, "msg body".getBytes());

    4、延时队列如何通过rabbitmq来实现呢?

    第一种:

      原理:生产者生产一条延时消息,根据需要延时时间的不同,设置不同的延时队列,每个队列都设置了不同的TTL属性,并绑定在同一个死信交换机中,消息过期后,根据routingkey的不同,又会被路由到不同的死信队列中,再等待消息超时,将消息转发到指定的Router队列。消费者只需要监听对应的死信队列进行处理即可。

    第二种:使用rabbitmq插件实现。

    如果不能实现在消息粒度上添加TTL,并使其在设置的TTL时间及时死亡,就无法设计成一个通用的延时队列。

    https://www.cnblogs.com/shihaiming/p/11081948.html

    https://www.cnblogs.com/mfrank/p/11260355.html

    
    
  • 相关阅读:
    Altera的FPGA_常见问题汇总65
    图像处理中振铃现象 分类: 图像处理 2014-12-16 23:40 565人阅读 评论(0) 收藏
    空域高斯滤波与频域高斯滤波 分类: 图像处理 2014-12-13 14:52 560人阅读 评论(0) 收藏
    灰度世界算法(Gray World Algorithm) 分类: 图像处理 Matlab 2014-12-07 18:40 874人阅读 评论(0) 收藏
    Retinex系列之McCann99 Retinex 分类: 图像处理 Matlab 2014-12-03 11:27 585人阅读 评论(0) 收藏
    Retinex系列之Frankle-McCann Retinex 分类: Matlab 图像处理 2014-12-01 21:52 538人阅读 评论(2) 收藏
    Tenegrad评价函数 分类: 图像处理 Opencv 2014-11-12 20:46 488人阅读 评论(0) 收藏
    Base64编码与解码 分类: 中文信息处理 2014-11-03 21:58 505人阅读 评论(0) 收藏
    VS2010下安装Opencv 分类: Opencv 2014-11-02 13:51 778人阅读 评论(0) 收藏
    循环队列 分类: c/c++ 2014-10-10 23:28 605人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/lgg20/p/12521256.html
Copyright © 2011-2022 走看看