Как правильно слить очередь с быстрым производителем?
У меня есть ситуация, когда мне нужно истощить очередь 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 мс кажется немного произвольной. Возможно, что мы будем бесконечно зацикливаться (т. Е. Производитель выдает>= 1 сообщение каждые 500 мс)
Альтернативой является использование receiveNoWait(). Это, насколько я понимаю, вытягивает сообщение, если оно доступно, или возвращает ноль, без тайм-аута. Однако, согласно ЭТОЙ статье:
Не все JMS-провайдеры немедленно возвращаются с сообщением, если вы вызываете receiveNoWait (), и в брокере могут быть сообщения, поэтому стоит подождать секунду или около того, чтобы убедиться, что очередь действительно опустошена.
Так есть ли более надежный способ сделать это с помощью программного подхода? В качестве альтернативы есть функция стока, которая поставляется с администратором Tibco EMS?
2 ответа
В TIBCO EMS Admin вы можете просто выполнить команду
PURGE QUEUE <queue name>
удалить все сообщения из него. Для нескольких очередей вы можете сделать
PURGE ALL QUEUES <pattern using '>' and '*' as wildcards>
Обратите внимание, что кроме интерфейса командной строки EMS Admin, есть также Java-API для выдачи таких команд администратора непосредственно из Java-программы.
Вы можете установить срок действия сообщения, если сообщение не требуется по истечении определенного периода времени. Это обеспечит отправку сообщения из очереди после истечения срока его действия. Простой вызов receive() с таймаутом может быть использован в дополнение к истечению срока действия. Прием будет работать, если в очереди есть сообщения. Если сообщение находится в состоянии без фиксации или заблокировано каким-либо процессом, только тогда получающий вызов не сможет получить это сообщение.