【问题标题】:MQ - Handling of messages exceeding max length moving to dead queueMQ - 处理超过最大长度的消息移动到死队列
【发布时间】:2018-12-07 11:16:14
【问题描述】:

这是一个普遍的问题。假设我在本地有一个队列管理器。我有一个传输队列/远程队列定义设置,通过它我连接到目标队列管理器队列。如果目标队列管理器队列的最大消息长度容量为 1000,并且如果我放置的消息长度超过该长度,那么它会自动移动到目标队列管理器死信队列,前提是我的传输队列最大消息长度大于我输入的长度。这是预期的行为。但是 MQ 世界上有什么方法可以处理这个问题而不是将其移至死队列?还是应用程序自行负责不超过最大长度?

提前致谢。

【问题讨论】:

  • 我唯一一次看到队列的 MAXMSGL 设置为低于默认 4MB 的值是在 z/OS(大型机)队列管理器上,这通常设置为记录大小COBOL 程序正在等待读取。我认为如果长度大于应用程序可以处理的长度而不是在 MQ 级别执行此操作,但很多时候,应用程序读取消息并将其移动到它自己的“坏消息”队列会更好COBOL 程序非常陈旧,没有人有时间维护它们。
  • 因为程序无法更改或没有人愿意更改它们,最好在 MQ 级别进行更改,以允许这些消息进入 DLQ 并且不会阻止应用程序处理大小合适的消息。
  • 通过快速评论回答您的问题,如果您想从 MQ 配置中确保应用程序放入 QREMOTE 不能放入大于 1000 字节的消息,您可以设置 @ XMITQ 本身上的 987654321@。这只有在XMITQ 不与其他需要放置大于1000 字节的消息的QREMOTE 对象共享时才可行。
  • 另一个选项,如果应用程序放置的是客户端连接,您可以在 SVRCONN 频道上设置 MAXMSGL(1000),同样,这只有在应用程序使用该频道放置的唯一消息是不大于 1000 字节。您可能还需要为MQMD 留出一些额外空间,因此请测试这些选项中的任何一个以确保它们正常工作。
  • 您可以在目的地配置接收通道,使其不放入DLQ。在通道上查找 USEDLQ 参数。然而,这意味着对于持久消息,通道将停止,这不是一种改进。非持久性消息将被丢弃。顺便说一句,您希望有什么替代行为?

标签: ibm-mq


【解决方案1】:

将默认的最大消息长度(即 MAXMSGL)从 4MB 更改为较小的值是个坏主意。

误区:MQ 确实根据最大消息长度字段中的值分配空间。将其设置为非常小的值或非常大的值与磁盘空间无关。 MQ 只写入真实消息的大小/数量。

其次,应用程序团队应该告诉 MQAdmin 应用程序将发送的最大消息是什么。如果他们说 10MB,那么 MQAdmin 可以增加最大值。消息长度为 10MB 或稍大一点,即 12MB。

可以使用的最大值是 100MB。

注意:MQAdmin 将需要增加最大值。消息长度:通道、XMITQ、本地队列和死信队列,用于任何大于默认大小 4MB 的消息,否则将不会流动。

【讨论】:

  • 别忘了QMGR 本身需要更新。同样在队列管理器之间,“发送方”和“接收方”通道以及应用程序用于 PUT 或 GET 更大消息的任何 SVRCONN 通道都需要更新。如果是到SVRCONN的客户端连接,如何增加客户端MAXMSGL在某些情况下取决于MQ的API和版本以及如何指定连接细节。
  • 如果连接是客户端到 QMgr (SVRCONN),则应用程序将收到许多原因代码之一,而不是让消息进入死信队列 (DLQ)。即 MQRC_MSG_TOO_BIG_FOR_Q、MQRC_MSG_TOO_BIG_FOR_CHANNEL 等。
  • Roger,我同意你的观点,我只是在你的上一个注释中添加了一些附加信息,以说明 MQAdmin 需要增加什么以允许大于 4MB 的消息。 ex MAXMSGL 需要为以下每个增加:CCDT CLNTCONN (or equivalent setting appropriate to API used) > QMGR (where PUT happens) > SVRCONN > XMITQ > SDR (or equivalent) -> RCVR (or equivalent) > QMGR (where GET happens) > QLOCAL > SVRCONN > CCDT CLNTCONN (or equivalent setting appropriate to API used)
【解决方案2】:

感谢 Roger 和 JoshMc。事实上,我尝试了两种选择,客户端到 QM 以及 QM 和 QM 之间。客户端到 QM 很好,因为客户端收到错误代码并且基本上没有任何反应。但问题只存在于发送方 QM 和接​​收方 QM 之间。我所看到的主要是只有一个具有最大消息长度的传输队列来连接到特定的队列管理器。所有不同的远程连接/队列都使用该传输队列。因此,如果发送者犯了一个错误,发送了一个比目标队列无法接受的大消息,它通常最终会通过传输队列但在目标失败并到达目标的死队列。现在目的地所有者被警告/或需要对他没有犯的错误采取一些补救措施。这就是我问这个问题的全部原因。非常感谢你们为我提供了更多的光和时间。

我认为 Morag Hughson 提供了一些东西让我尝试,但它仍然会产生负面影响。但我一直在寻找类似的东西,我们可以在 MQ 级别进行控制,以不允许消息进入目标死队列。

【讨论】:

  • 如果客户端无法发送到 QM,那么您不必担心发送方 QM 到接收方 QM。虽然您说只有一个 XMITQ,但您始终可以为不同的 MAXMSGL 定义具有 XMITQ 的不同 CHL。如果只有几个不同的尺寸,这可能没问题。
  • 是的 JoshMc,这将是一个很好的解决方案。但正如你所说,只要沟通不因更多不同的需求而变得复杂。否则我们最终会消耗大量资源。从本主题中的所有讨论和观点来看,解决方案似乎是一条狭窄的道路,需要权衡取舍。谢谢,与发布问题时相比,我现在有了一些知识。
猜你喜欢
  • 2012-03-31
  • 1970-01-01
  • 2012-07-24
  • 2011-06-02
  • 2014-09-04
  • 1970-01-01
  • 2019-10-21
  • 2014-07-20
  • 2013-04-09
相关资源
最近更新 更多