Thursday, 13 September 2018

How to avoid receiving same message twice in RabbitMQ

In this post, we will see how to avoid receiving / processing duplicate message more than once in RabbitMQ.

Background:
RabbitMQ is a messaging queue software (also called message broker) that implemented the Advanced Message Queuing Protocol (AMQP). The producer submits message on queue and consumer processes it. But sometimes we use to see the issue with duplicate processing of same message in case where consumer decide to acknowledge message after processing it.

Problem Statement and Solution:
Suppose there is a message that is published into message broker. There can be two scenario in case of consumers for this message type:

  • Single Consumer
    • Consumer receives the message and start processing it and dies (or hung) in betweenIn this case if the acknowledgement has not been send back to RabbitMQ message broker, the message will remain in queue and when the consumer starts again, it will receive the same message. 
      • Solution: In the above case, developer needs to know if the business logic is processed or not. So developer needs to implement status of the message in either database or flat file with the message id. If same message is received after consumer restarts, developer can take a call to process again or not
    • Consumer receives message and processed it but still it receives same message again:
      • Solution: If you are facing this issue, then the problem lies in the heart-beat  timeout between consumer and RabbitMQ. So here consumer has received the message and its thread is processing it but due to missed heart-beat (due to network latency or whatever reason) RabbitMQ assumes the consumer has died and it closes the connection with consumer. Meanwhile as the consumer thread is active, it is still processing the message and completed it successfully but it was unable to acknowledge it back to RabbitMQ. The solution lies in increasing the heart-beat timeout so that it doesn't misses the heart-beat.
  • Multiple Consumer:
    • Consumer receives the message and start processing it and dies (or hung) in betweenIn this case if the acknowledgement has not been send back to RabbitMQ message broker, the message will remain in queue and it has been send back to another consumer waiting for message
      • Solution: In the above case, developer needs to know if the business logic is processed or not. So developer needs to implement status of the message in either database or flat file with the message id. If same message is received after consumer restarts, developer can take a call to process again or not
    • Consumer receives message and processed it but other consumer receives same message again:
      • Solution: If you are facing this issue, then the problem lies in the heart-beat  timeout between consumer and RabbitMQ. So here consumer has received the message and its thread is processing it but due to missed heart-beat (due to network latency or whatever reason) RabbitMQ assumes the consumer has died and it closes the connection with consumer. Meanwhile as the consumer thread is active, it is still processing the message and completed it successfully but it was unable to acknowledge it back to RabbitMQ. The solution lies in increasing the heart-beat timeout so that it doesn't misses the heart-beat. 
Thats all about problems related to consumer receiving duplicate messages and its possible solutions. If you have query / suggestion, please feel free to post in comment section. Thanks.

Wednesday, 5 September 2018

Max Priority Queue Implementation in Java

In this post, we will see how to implement max priority queue in Java.

Background:
Priority Queue is an non-blocking unbounded queue, the elements of which are arranged in either natural order (if no comparator is provided) or comparator provided as part of constructor. In both scenario, the queue is arranged in ascending order and the head of queue will have least value. Honestly, this does not make sense for Priority Queue to arrange elements in ascending order which can be called as Min Priority Queue

Have the elements arranged in reversed order will make it Max Priority Queue

Implementation:

Now the question arises, how can we make the Priority Queue as Max Priority Queue with the api provided by Java.
Here is the code example for Max Priority Queue in Java


package com.blogspot.tech693;

import java.util.Collections;
import java.util.PriorityQueue;

public class MaxPriorityQueue{

 public static void main(String[] args){
  // Generic Priority Queue -- Natural order
  PriorityQueue pq = new PriorityQueue<>(6);
  pq.add(4);
  pq.add(2);
  pq.add(1);
  pq.add(6);
  pq.add(5);
  
  System.out.println("Generic / Min Priority Queue::" + pq.poll());
  System.out.println("Generic / Min Priority Queue::" + pq.poll());
  
  // Max Priority Queue Example
  PriorityQueue pq1 = new PriorityQueue<>(6, Collections.reverseOrder());
  pq1.add(4);
  pq1.add(2);
  pq1.add(1);
  pq1.add(6);
  pq1.add(5);
  
  System.out.println("Max Priority Queue::" + pq1.poll());
  System.out.println("Max Priority Queue::" + pq1.poll());
 }
 
}



Output:

Generic / Min Priority Queue::1

Generic / Min Priority Queue::2

Max Priority Queue::6

Max Priority Queue::5


Explanation:
In the above code example, we tried to achieve Priority Queue in descending order. I strongly believe the head of the queue should be the highest element. By using Collections.reverseOrder() method we can conver the Priority Queue into Max Priority Queue.

That's all for Max Priority Queue Implementation in Java. If you have questions / suggestions, please mention in comments sections. Thanks. 

Related Articles:

You may also like: