开发者

Alternative to acking messages from QueueBrowser

I'm relatively new to JMS. I have a requirement as such:

events are published to a queue. Each event has a UserID associated with it, and the events for a given UserID must be processed in order. Sometimes an event cannot be processed immediately, so we'd like to temporarily ignore events from that UserID while continuing to consume events for the other UserIDs in the queue.

Initially I thought that a QueueBrowser might help, a la:

Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
QueueBrowser queueBrowser = session.createBrowser(eventQueue);
Enumeration messages = queueBrows开发者_如何学Goer.getEnumeration();
HashSet<Integer> busylist = new HashSet<Integer>(); // Keeps track of busy users
while (messages.hasNextElement())
{
  t.begin()
  Message msg = (Message) messages.getNextElement();
  Integer userId = msg.getIntProperty("UserID");
  if (busylist.contains(userId))
    continue;
  boolean userIsBusy = process(msg);
  if (userIsBusy)
  {
    busylist.add(userId);
    continue;
  }
  msg.acknowledge();
  t.commit();
}

The idea is to consume everything from the queue, but when a user is busy, record that in busylist and continue on to the next message. The above code might be called once per minute. After testing something similar to the above code I found that the acknowledge() message on messages from a queuebrowser does nothing by design.

My question is, how might I achieve something similar to the above? One solution I see is to create a MessageConsumer for every message I want to ack using a message selector to select out the individual message... It seems a bit inefficient to me. Are there other ways to do this?

I don't think an acceptable solution would be one queue per user. There're millions of users.


Not to immediately sidetrack your approach, but could you set a time-to-live on messages when they are sent ? That way, if a user does not consume their messages within the designated time, their messages will automatically be purged by the JMS engine.

Alternatively, pursuing your approach, rather than creating a message consumer per message per idle user, batch the message IDs into sets of n messages. When the batch is full, or the browser reaches the end of the message set, direct the message consumer to use a selector which specifies all the idle message IDs and consume them.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜