替代来自QueueBrowser的acking消息

时间:2011-09-07 01:33:09

标签: jms

我对JMS比较陌生。我有这样的要求:

事件发布到队列中。每个事件都有一个与之关联的UserID,并且必须按顺序处理给定UserID的事件。有时事件无法立即处理,因此我们希望暂时忽略该UserID中的事件,同时继续使用队列中其他UserID的事件。

最初我认为QueueBrowser可能有所帮助,la:

Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
QueueBrowser queueBrowser = session.createBrowser(eventQueue);
Enumeration messages = queueBrowser.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();
}

这个想法是消耗队列中的所有内容,但是当用户忙时,将其记录在总线列表中并继续下一个消息。上述代码可能每分钟调用一次。 在测试类似于上面代码的内容之后,我发现来自queuebrowser的消息上的acknowledge()消息没有做任何按设计

我的问题是,我怎样才能实现与上述类似的东西?我看到的一个解决方案是为每个我想要使用消息选择器来消息的消息创建一个MessageConsumer来选择单个消息......这对我来说似乎有点低效。还有其他方法吗?

我不认为可接受的解决方案是每个用户一个队列。有数百万用户。

1 个答案:

答案 0 :(得分:0)

不要立即偏离您的方法,但是您可以在发送邮件时设置生存时间吗?这样,如果用户在指定时间内没有使用他们的消息,他们的消息将自动被JMS引擎清除。

或者,追求您的方法,而不是为每个空闲用户按消息创建消息使用者,将消息ID批量分组为 n 消息。当批处理已满或浏览器到达消息集的末尾时,指示消息使用者使用指定所有空闲消息ID的选择器并使用它们。