官术网_书友最值得收藏!

How to let messages expire on specific queues

In this recipe, we show a second way to specify a message TTL. This time, it is not a property of the message itself but of the queue where the message is buffered. In this case, the producer simply publishes normal messages to the exchange, so it's possible to bind both a standard queue and a queue where messages expire.

To remark on this aspect, here it's the consumer that creates the customized queue. The producer is quite standard.

As in the preceding recipe, you can find the three sources at Chapter02/Recipe02/Java/src/rmqexample.

Getting ready

To use this recipe, we need to set up the Java development environment, as indicated in the Introduction section of Chapter 1, Working with AMQP.

How to do it...

We are now showing the needed steps to create a queue with a specific message TTL. In our explanatory example, the following steps are performed in the Consumer.java file:

  1. Create or declare the exchange as follows:
    channel.exchangeDeclare(exchange, "direct", false);
  2. Create or declare the queue, specifying a 10,000 milliseconds timeout to the x-message-ttl optional argument as follows:
    Map<String, Object> arguments = new HashMap<String, Object>();
    arguments.put("x-message-ttl", 10000);
    channel.queueDeclare(queue, false, false, false, arguments);
  3. Bind the queue to the exchange where the messages are going to come from:
    channel.queueBind(queue, exchange, routingKey);

How it works...

Again, in this example, we are supposed to have a producer that sends JVM statistics to RabbitMQ for eventual analysis. Eventual because the Producer.java file sends them to an exchange and messages will be lost if there are no consumers connected.

A consumer that wants to monitor and analyze those statistics has the following three choices:

  • To bind with a temporary queue, invoking channel.queueDeclare() without arguments
  • To bind with a non-autodelete, named queue
  • To bind with a non-autodelete, named queue and specifying x-message-ttl, as shown in step 2.

In the first case, the consumer will get real-time statistics only but it won't be able to perform an analysis on any data sent when it's down.

In the second case, to let the consumer get messages sent when it's down, it can use a named queue (persistent too eventually). But if it is down for a long time, when restarted, it will have a huge backlog to recover from before it starts being effective as a monitor. So, it would probably just trash most of the old messages in the queue.

The third option, the argument of our recipe, is just this, but trashing old messages is performed by RabbitMQ itself with benefits for both the consumer and the broker itself.

There's more...

When setting a per-queue TTL, as seen in this recipe, messages are not dropped (or dead lettered, refer to the Managing rejected or expired messages recipe later in this chapter) as soon as the timeout arrives, but only when a consumer tries to consume them. At this point, these messages are silently dropped and the first ready, not expired message is sent to the consumer.

When using queue TTL, this is a minor difference, but using per-message TTL, as seen in the previous recipe, it's possible to have expired messages in the broker queue behind regular messages.

In this case, those expired messages still occupy resources (memory) and are counted in the broker statistics, until they won't reach the head of the queue.

See also

The expired messages can be recovered in this case too. Refer to the Managing rejected or expired messages recipe.

主站蜘蛛池模板: 青铜峡市| 涟水县| 衡南县| 班玛县| 文山县| 安陆市| 霸州市| 靖西县| 黎城县| 上杭县| 克拉玛依市| 嘉祥县| 防城港市| 岳普湖县| 博兴县| 咸宁市| 安塞县| 华阴市| 陕西省| 衡水市| 尉犁县| 聂拉木县| 偏关县| 图木舒克市| 平罗县| 福安市| 德惠市| 屏东市| 阜南县| 隆林| 晋城| 文山县| 资溪县| 育儿| 来凤县| 海门市| 格尔木市| 云霄县| 旬阳县| 凤城市| 宁明县|