2016-06-14 3 views
0

У меня есть приложение C#, которое настраивает множество слушателей MQ (несколько потоков и потенциально несколько серверов, каждый со своими собственными слушателями). Есть некоторые сообщения, которые оторвутся от очереди, которую я хочу оставить в очереди, перейдем к следующему сообщению в MQ, но потом при некоторых обстоятельствах мне захочется вернуться, чтобы перечитать эти сообщения ....NET IBM MQ Listener не подтвержденное сообщение и чтение с начала очереди

var connectionFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ).CreateConnectionFactory(); 
connectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, origination.Server); 
connectionFactory.SetIntProperty(XMSC.WMQ_PORT, int.Parse(origination.Port)); 
connectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, origination.QueueManager); 
connectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, origination.Channel); 

var connection = connectionFactory.CreateConnection(null, null); 
_connections.Add(connection); 

var session = connection.CreateSession(false, AcknowledgeMode.ClientAcknowledge); //changed to use ClientAcknowledge so that we will leave the message on the MQ until we're sure we're processing it 
_sessions.Add(session); 

var destination = session.CreateQueue(origination.Queue); 
_destinations.Add(destination); 

var consumer = session.CreateConsumer(destination); 
_consumers.Add(consumer); 

Logging.LogDebugMessage(Constants.ListenerStart); 

connection.Start(); 
ThreadPool.QueueUserWorkItem((o) => Receive(forOrigination, consumer)); 

Тогда у меня есть ...

if (OnMQMessageReceived != null) 
{ 
    var message = consumer.Receive(); 
    var identifier = string.Empty; 

    if (message is ITextMessage) 
    { 
     //do stuff with the message here 
     //populates identifier from the message 
    } 
    else 
    { 
     //do stuff with the message here 
     //populates identifier from the message 
    } 

    if (!string.IsNullOrWhiteSpace(identifier)&& OnMQMessageReceived != null) 
    { 
     if(some check to see if we should process the message now) 
     { 
      //process message here 
      message.Acknowledge(); //this really pulls it off of the MQ 

      //here is where I want to trigger the next read to be from the beginning of the MQ 
     } 
     else 
     { 
      //We actually want to do nothing here. As in do not do Acknowledge 
      //This leaves the message on the MQ and we'll pick it up again later 
      //But we want to move on to the next message in the MQ 
     } 
    } 
    else 
    { 
     message.Acknowledge(); //this really pulls it off of the MQ...its useless to us anyways 
    } 
} 
else 
{ 
    Thread.Sleep(0); 
} 

ThreadPool.QueueUserWorkItem((o) => Receive(forOrigination, consumer)); 

Так пару вопросов:

  1. Если я не признаю сообщения оно остается на MQ, не так ли?

  2. Если сообщение не подтверждено, то по умолчанию, когда я прочитал из MQ снова с тем же слушателем, он читает следующий и не переходит в начало, правильно?

  3. Как изменить прослушиватель, чтобы в следующий раз, когда я прочитал, я начинаю в начале очереди?

ответ

2

Оставляя сообщения в очереди, это анти-шаблон. Если вы не хотите или не можете обработать сообщение в определенный момент вашей логики, то у вас есть несколько вариантов:

  • получить его из очереди и поместить в другую очереди/тему для замедленного/различная обработка.
  • Получите это от очереди и дамп в базу данных, плоский файл - независимо от того, хотите ли вы обработать его за пределами потока сообщений или вообще не хотите обрабатывать.
  • Если это возможно, вы можете изменить производителя сообщений, чтобы он не смешивал сообщения с различными требованиями к обработке в той же очереди/теме.

В любом случае не оставляйте сообщение в очереди и всегда переходите к следующему сообщению. Это сделает приложение более предсказуемым и легче рассуждать. Вы также избегаете всех проблем с производительностью. Если ваше приложение или когда-либо становится чувствительным к последовательности доставки сообщений, то ручное подтверждение выбранных сообщений также будет несовместимо с ним.

на вопросы:

  1. В спецификации JMS расплывчато о поведении неподтвержденных сообщений - они могут быть доставлены в порядке, и это не определено, когда именно тогда, когда они будут доставлены. Кроме того, вызов метода подтверждения подтвердит все ранее принятые и неподтвержденные сообщения - вероятно, не то, что вы имели в виду.

  2. Если вы оставляете сообщения позади, слушатель может вернуться или не вернуться немедленно. Если вы перезапустите его, он, конечно, запустится заново, но пока он сидит там, ожидая сообщений, он зависит от реализации.

Так что, если вы попытаетесь сделать свою работу над дизайном, вы можете получить такую ​​работу при определенных обстоятельствах, но она не будет предсказуемой или надежной.

Смежные вопросы