Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .net XMS中的IBM-MQ读卡器逐个确认已处理的消息_C#_.net_Ibm Mq - Fatal编程技术网

C# .net XMS中的IBM-MQ读卡器逐个确认已处理的消息

C# .net XMS中的IBM-MQ读卡器逐个确认已处理的消息,c#,.net,ibm-mq,C#,.net,Ibm Mq,我正在实现一个组件,该组件读取特定队列中可用的所有消息,但只应在消息内容得到处理和持久化后,异步从队列中删除消息。我们读取消息的速度比确认消息的速度快(例如,在准备确认第一条消息之前,我们可以读取10条消息)。当前的实现使用XMS API,但是如果XMS不适合这些用途,我们可以切换到MQI 我们尝试了两种方法来解决这个问题,但都有缺点,使他们无法接受。我希望有人能提出更好的办法 第一个实现在专用线程中使用IMessageConsumer,读取所有消息并发布其可用内容。处理完消息后,将调用mess

我正在实现一个组件,该组件读取特定队列中可用的所有消息,但只应在消息内容得到处理和持久化后,异步从队列中删除消息。我们读取消息的速度比确认消息的速度快(例如,在准备确认第一条消息之前,我们可以读取10条消息)。当前的实现使用XMS API,但是如果XMS不适合这些用途,我们可以切换到MQI

我们尝试了两种方法来解决这个问题,但都有缺点,使他们无法接受。我希望有人能提出更好的办法

第一个实现在专用线程中使用
IMessageConsumer
,读取所有消息并发布其可用内容。处理完消息后,将调用
message.Acknowledge()
方法。会话是使用
AcknowledgeMode.ClientAcknowledge
创建的。这种方法的问题在于,根据文档,它会确认(并删除)所有已收到的未确认消息。在上面的示例中,这意味着所有10条已读消息都将在第一次调用时得到确认。所以这并不能真正解决问题。由于我们需要的读取吞吐量,我们无法真正修改此解决方案,以便在读取第二条消息之前等待第一条消息的确认,等等


第二个实现在一个确定的线程中使用
IQueueBrowser
,读取所有消息并发布其内容。这不会在队列读取时从队列中删除消息。然后,一个单独的专用线程(在BlockingQueue上)等待已处理消息的JMS消息ID。对于其中的每一个,它然后构造一个专用的
IMessageConsumer
(使用带有JMSMessageID的消息选择器)来读取消息并确认它。(XMS文档中关于队列浏览器的部分建议将
IQueueBrowser
与专用
IMessageConsumer
进行配对。)此方法确实可以按预期工作,但正如人们所想象的,MQ服务器上的CPU过于密集。

问题中提出的两种方法似乎都依赖于应用程序的单个实例。使用多个应用程序实例、事务处理会话和提交有什么问题?性能报告(这些报告的名称类似于MP**)都表明多个应用程序实例可以最大限度地提高吞吐量,而水平扩展是场景中最常用的方法之一

这种设计可以是多个应用程序实例,也可以是同一应用程序中的多个线程。使其正常工作的关键是要记住,事务的作用域是连接句柄。这意味着多线程应用程序必须为每个连接实例分派一个单独的线程,并且消息在同一线程中读取

处理流程是,使用事务会话,应用程序对队列执行正常的
MQGet
,根据需要处理消息内容,然后发出
MQCommit
。(我将在示例中使用MQ本机API名称,因为这与语言无关。)如果这是XA事务,应用程序将调用
MQBegin
来启动事务,但对于单阶段提交,则假定事务。在这两种情况下,
MQCommit
结束从队列中删除消息的事务。当消息处于同步点下时,其他应用程序实例无法检索它们;MQ只是传递下一条可用消息。如果回滚事务,则来自任何线程的下一个
MQGet
将检索该事务,假设FIFO传递

中有一些示例:
[WMQ install home]\tools\dotnet\samples\cs\xms\simple\WMQ\

…和
SimpleXAConsumer.cs
是一个示例,它显示了该产品的XA版本。非XA版本更简单,因为您不需要外部协调器、
MQBegin
动词等等。如果从其中一个开始,请确保它们没有指定队列的独占使用,并且可以使用相同的配置启动多个实例。或者,以示例中包括连接创建、消息处理、连接关闭和销毁的部分为例,并将所有这些内容包装到一个thread spawner类中


[在此处插入有关使用最新版本的类的常见建议。]

是的,这就是行为,消息不能被随机确认。一条消息确认将确认所有以前的消息。在MQ.NET中也没有选项。根据您的描述,您似乎可以通过一次ack呼叫确认所有消息,但您更关心吞吐量。您期望的吞吐量是多少?预期吞吐量:最活跃队列上每天最多100万条消息,MQ服务器上所有队列上每天最多1000万条消息。请澄清:我们无法按顺序读取和处理每条消息的主要原因(在读取下一条消息之前)实际处理有相当长的前置时间,这就是为什么我们需要同时处理许多消息。您提出的两种方法似乎都依赖于应用程序的单个实例。使用多个应用程序实例、事务处理会话和提交有什么问题?性能报告都表明,多个应用程序实例可以最大限度地提高吞吐量,水平扩展是您的场景中最常用的方法之一。@T.Rob您将如何构建它?多个线程,每个线程都有自己的会话和使用者;每个人都在读一条信息,然后等待它被处理?另外:你能把你的评论变成一个答案吗:-)所以我已经试过了,它按照描述的那样工作。但我有一个后续问题:我想在这个设置中没有简单的方法跳过特定的消息