linux 查看ibm mq队列消息,.NET IBM MQ侦听器未确认的消息并从队列的开头读取

本文讨论了一个C#应用设置IBM MQ监听器的问题,该应用需要在某些情况下保留队列中的消息以便稍后重新读取。文章探讨了如何在不确认消息时保持消息在队列上,并询问了关于如何从队列开始处重新读取消息的疑问。解决方案建议不要将消息留在队列中,而是采用其他处理方式,如转移到不同队列或数据库,以提高应用的可预测性和性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I have a C# application that sets up numerous MQ listeners (multiple threads and potentially multiple servers each with their own listeners). There are some messages that will come off the queue that I will want to leave on the queue, move on to the next message on the MQ, but then under some circumstances I will want to go back to re-read those messages...

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));

Then I have...

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));

So a couple of questions:

If I do not acknowledge the message it stays on the MQ, right?

If the message is not acknowledged then by default when I read from the MQ again with the same listener it reads the next one and does not go to the beginning, right?

How do I change the listener so that the next time I read I start at the beginning of the queue?

Solutions1

Leaving messages on a queue is an anti-pattern. If you don't want to or cannot process the message at a certain point of your logic, then you have a number of choices:

Get it off the queue and put to another queue/topic for a delayed/different processing.

Get it off the queue and dump to a database, flat file - whatever, if you want to process it outside of messaging flow, or don't want to process at all.

If it is feasible, you may want to change the message producer so it doesn't mix the messages with different processing requirements in the same queue/topic.

In any case, do not leave a message on the queue, and always move forward to the next message. This will make the application way more predictable and easier to reason about. You will also avoid all kinds of performance problems. If your application is or may ever become sensitive to the sequence of message delivery, then manual acknowledgement of selected messages will be at odds with it too.

To your questions:

The JMS spec is vague regarding the behavior of unacknowledged messages - they may be delivered out of order, and it is undefined when exactly when they will be delivered. Also, the acknowledge method call will acknowledge all previously received and unacknowledged messages - probably not what you had in mind.

If you leave messages behind, the listener may or may not go back immediately. If you restart it, it of course will start afresh, but while it is sitting there waiting for messages it is implementation dependent.

So if you try to make your design work, you may get it kind of work under certain circumstances, but it will not be predictable or reliable.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值