【问题标题】:How to properly drain a Queue with a fast producer?如何使用快速生产者正确排空队列?
【发布时间】:2014-03-14 03:38:00
【问题描述】:

我遇到需要排空 JMS(特别是 Tibco EMS)队列的情况。用例是,如果我们要进行大规模中断,队列会建立起来,处理它会花费很长时间。因此,我们希望排空队列,并执行冷启动类型的例程以获取当前状态。

到目前为止,我的代码如下:

 int count = 0;
    Message msg = null;
    while ((msg = connection.receive(timeout)) != null) {
        count++;
    }
    System.out.println(count + " msgs removed from queue: " + queueName);

基本上它会循环接收消息,直到timeout在收到消息之前过期,表明队列为空。

我的问题涉及timeout 这个值。假设我们在队列中有一个非常快的生产者,设置一个 500 毫秒的超时似乎有点武断。我们可能会无限循环(即生产者每 500 毫秒产生 >= 1 条消息)

替代方法是使用receiveNoWait()。据我了解,这会在消息可用时提取消息,或者返回 null,而不涉及超时。但是,根据THIS文章:

如果您调用 receiveNoWait(),并非所有 JMS 提供程序都会立即返回消息,并且代理上可能有消息,因此值得等待一秒钟左右,以确保队列确实已耗尽。

那么有没有更稳健的方法可以通过程序化方法来做到这一点?或者,Tibco EMS 管理员是否有排水功能?

【问题讨论】:

    标签: java jms message-queue tibco tibco-ems


    【解决方案1】:

    如果在特定时间段后不需要消息,您可以设置消息的过期时间。这将确保消息在过期后离开队列。除了到期之外,还可以使用带有超时的简单接收()调用。如果队列中有消息,接收将起作用。如果消息处于未提交状态或被某个进程锁定,那么接收调用将无法获取该消息。

    【讨论】:

      【解决方案2】:

      在 TIBCO EMS Admin 中,您可以简单地发出命令

      PURGE QUEUE <queue name>
      

      从中删除所有消息。对于多个队列,您可以这样做

      PURGE ALL QUEUES <pattern using '>' and '*' as wildcards>
      

      请注意,除了 EMS Admin 的命令行界面外,还有一个 Java-API 可以直接从 Java 程序内部发出此类 Admin 命令。

      【讨论】:

        猜你喜欢
        • 2016-08-27
        • 2018-10-10
        • 2011-06-27
        • 2015-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-21
        相关资源
        最近更新 更多