0
votes

I've a JMS Topic that produces a unique messages.

And I have a simple webapp deployed on n machines (clients), All what it do is to put the consumed msg into another system (the destination system).

Note:

  • I do NOT have control on the JMS.
  • I DO have control on the Clients.
  • I do NOT have control on the destination system that will receive the msg by the client.

My Question is:

How to make sure that the message written once (into the destination system) by one of these clients and never being written again by another client (as if the JMS was a Queue not topic), knowing that each msg have a uniqueId?

I am thinking of two solutions:

  1. create another JMS Queue that consumes from that topic, and this queue is gonna consumed by one of the n clients once for each msg.

  2. Have some sort of shared location (memcache) that have the message Ids for consumed msgs, and before send the consumed msg to destination system by the client, I'll have to check if the shared storage (memcache) have this id before, if not then send to destination system.

What do you think?

Update:

The system that eventually got the message is not a RDBMS and is not even under my control. I just deliver some msg from one system to another. (actually it is Apache Flume by is not under my control)

2

2 Answers

1
votes
  • Using another queue possilby results in another problem: Exactly one of your n machines must listen on the topic. If you have to make sure that no message ist lost, you have to synchronize the subscribers somehow. Adding a separate subscriber increases system complexity.

  • Adding another storage (shared memory cluster, memcache, ...) increases the system complexity (and you already have a common storage).

So the best thing really is to use a queue instead of a topic. You can't change this, therefore I suggest this option:

  • All JMS messages have a unique message ID. You can store this ID along in the database together with a unique index on that column. So you could just insert (and ignore a unique constraint violation error). Not really nice, but it works in the cluster, and it does not increase system complexity. A variation is to check before, if the message already exists in the database.
0
votes

If possible, I would not deploy n clients listening on the topic. Because the job done by the clients is to forward only a single copy of message to another component or a database every time a message is published. Instead I would go for creating one durable subscription and only one client listening on that subscription. This client will forward the messages to database. If the client is not running, the messages will be held by the messaging provider and delivered when the client goes running again.