Websphere MQ,接收大(100 MB)消息
Websphere MQ, receive large (100 MB) message
我正在尝试从 Websphere MQ 队列中读取一个 100 MB 的文件。文件应包含大约。 800.000 条记录。但是在某个行号(通常在 90.000 左右)之后,我只得到空的(或者可能是 �,这取决于我尝试查看文件的方式)。
我被告知队列应该允许 100 MB 的消息。
我的代码:
var mqQueueManager = getMqQueueManager(ConfigurationManager.AppSettings["MQ_QueueManager"]);
var mqQueue = mqQueueManager.AccessQueue(mqReceiveQueueName,
MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_FAIL_IF_QUIESCING);
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.Options = MQC.MQGMO_NO_WAIT;
for (int i = 0; i < maxMessagesToRead; i++)
{
var mqMessage = new MQMessage();
mqQueue.Get(mqMessage, gmo);
messageTexts.Add(mqMessage.ReadString(mqMessage.MessageLength));
}
这段代码有问题吗?或者是发送方的错误?
目前还不清楚问的是什么,我相信这是问题的根源。虽然 MQ 确实可以处理最大 100MB 的消息,但这不是问题的读法。
I'm trying to read a 100 MB file from a Websphere MQ queue. File
should contain approx. 800.000 records. But after a certain row number
(usually around 90.000)
隐藏在该单个语句中的是对以下内容的引用:
- 文件
- 队列
- 记录
- 行
我相信您询问的每个人都对队列做出了回应,因此反复保证 MQ 可以处理 100MB 的消息。但是代码似乎正在重新组装一个文件,每个消息被分成一个record/row ].那是一个完全不同的用例。
一次拿这些,完全有可能在MQ中来回传递100MB的消息。这样做需要从 MAXMSGL
的 4MB 默认值配置该路径上的每个 QMgr、通道和队列。不太明显的是,如果使用线性日志 and/or 消息在同步点下处理,则必须有足够的日志 space 来包含多个 100MB 事务。默认的日志范围计数和大小预计不会有 100MB 的消息。最后,应用程序需要提供足够大的缓冲区,并确保不告诉 MQ 允许截断消息。
这种通过 MQ 移动文件的方法仅限于小于 100MB 的文件,但具有原子操作的明显优势 - 您可以 GET/PUT 整个文件或 none。没有遗漏的部分,没有乱序等等。这大大简化了代码。
第二种可能性是代码正在重组一个被拆分成许多消息的文件。似乎怀疑发布的代码片段实际上想要将多条 100MB 的消息附加到彼此,所以我假设它试图从许多消息中重新组合一个文件。 (我相信最多 800,000 条。)在这种情况下,问题在于单个工作单元中可以包含多少条消息。该代码片段省略了任何有意义的错误处理,因此我假设也省略了同步点处理。
重组文件时出现的错误包括乱序消息和丢失消息。即使是每个文件使用多条消息的最简单的基于 MQ 的文件移动器也需要使用同步点来确保整个文件作为一个单元发送或接收。但是 MQ 预计在一个工作单元中不会有 800,000 条消息,因此您需要同时调整日志范围 和 MAXUMSGS
做任何比微不足道的案件更多的事情。
当然,当文件被分割成许多消息时,移动文件并保证它们的完整性并不是微不足道的,当所有排列都被考虑在内时,结果看起来很像 MQ 托管文件传输。
回到问题上来,如果文件是在单个消息中传输的,并且没有设置API截断消息的选项,那么里面什么也没有MQ API 会在一定行数或消息长度后影响消息。在那种情况下,解释垃圾超过某个点的唯一方法是发送应用程序发送了它。 (比如分配了100MB的缓冲区,填充了50MB,然后发送了100MB的消息。)
但是,如果文件被分割成许多消息,如代码所示,则必须执行上述调整。这包括将 MAXUMSGS
提高到大于 800,000 的值(doc link) and ensuring that there's enough space in the Primary and Secondary log extents to hold a few large units of work. See Calculating the size of the log 了解详情。
顺便说一句,您可能还想每次都重置 MQGMO
,因为正如该对象的 Overview 中所述,它既是输入 又是 输出。
修改后的代码看起来更像这样:
MQGetMessageOptions gmo = new MQGetMessageOptions();
for (int i = 0; i < maxMessagesToRead; i++)
{
var mqMessage = new MQMessage();
gmo.Options = MQC.MQGMO_NO_WAIT;
mqQueue.Get(mqMessage, gmo);
我正在尝试从 Websphere MQ 队列中读取一个 100 MB 的文件。文件应包含大约。 800.000 条记录。但是在某个行号(通常在 90.000 左右)之后,我只得到空的(或者可能是 �,这取决于我尝试查看文件的方式)。
我被告知队列应该允许 100 MB 的消息。
我的代码:
var mqQueueManager = getMqQueueManager(ConfigurationManager.AppSettings["MQ_QueueManager"]);
var mqQueue = mqQueueManager.AccessQueue(mqReceiveQueueName,
MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_FAIL_IF_QUIESCING);
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.Options = MQC.MQGMO_NO_WAIT;
for (int i = 0; i < maxMessagesToRead; i++)
{
var mqMessage = new MQMessage();
mqQueue.Get(mqMessage, gmo);
messageTexts.Add(mqMessage.ReadString(mqMessage.MessageLength));
}
这段代码有问题吗?或者是发送方的错误?
目前还不清楚问的是什么,我相信这是问题的根源。虽然 MQ 确实可以处理最大 100MB 的消息,但这不是问题的读法。
I'm trying to read a 100 MB file from a Websphere MQ queue. File should contain approx. 800.000 records. But after a certain row number (usually around 90.000)
隐藏在该单个语句中的是对以下内容的引用:
- 文件
- 队列
- 记录
- 行
我相信您询问的每个人都对队列做出了回应,因此反复保证 MQ 可以处理 100MB 的消息。但是代码似乎正在重新组装一个文件,每个消息被分成一个record/row ].那是一个完全不同的用例。
一次拿这些,完全有可能在MQ中来回传递100MB的消息。这样做需要从 MAXMSGL
的 4MB 默认值配置该路径上的每个 QMgr、通道和队列。不太明显的是,如果使用线性日志 and/or 消息在同步点下处理,则必须有足够的日志 space 来包含多个 100MB 事务。默认的日志范围计数和大小预计不会有 100MB 的消息。最后,应用程序需要提供足够大的缓冲区,并确保不告诉 MQ 允许截断消息。
这种通过 MQ 移动文件的方法仅限于小于 100MB 的文件,但具有原子操作的明显优势 - 您可以 GET/PUT 整个文件或 none。没有遗漏的部分,没有乱序等等。这大大简化了代码。
第二种可能性是代码正在重组一个被拆分成许多消息的文件。似乎怀疑发布的代码片段实际上想要将多条 100MB 的消息附加到彼此,所以我假设它试图从许多消息中重新组合一个文件。 (我相信最多 800,000 条。)在这种情况下,问题在于单个工作单元中可以包含多少条消息。该代码片段省略了任何有意义的错误处理,因此我假设也省略了同步点处理。
重组文件时出现的错误包括乱序消息和丢失消息。即使是每个文件使用多条消息的最简单的基于 MQ 的文件移动器也需要使用同步点来确保整个文件作为一个单元发送或接收。但是 MQ 预计在一个工作单元中不会有 800,000 条消息,因此您需要同时调整日志范围 和 MAXUMSGS
做任何比微不足道的案件更多的事情。
当然,当文件被分割成许多消息时,移动文件并保证它们的完整性并不是微不足道的,当所有排列都被考虑在内时,结果看起来很像 MQ 托管文件传输。
回到问题上来,如果文件是在单个消息中传输的,并且没有设置API截断消息的选项,那么里面什么也没有MQ API 会在一定行数或消息长度后影响消息。在那种情况下,解释垃圾超过某个点的唯一方法是发送应用程序发送了它。 (比如分配了100MB的缓冲区,填充了50MB,然后发送了100MB的消息。)
但是,如果文件被分割成许多消息,如代码所示,则必须执行上述调整。这包括将 MAXUMSGS
提高到大于 800,000 的值(doc link) and ensuring that there's enough space in the Primary and Secondary log extents to hold a few large units of work. See Calculating the size of the log 了解详情。
顺便说一句,您可能还想每次都重置 MQGMO
,因为正如该对象的 Overview 中所述,它既是输入 又是 输出。
修改后的代码看起来更像这样:
MQGetMessageOptions gmo = new MQGetMessageOptions();
for (int i = 0; i < maxMessagesToRead; i++)
{
var mqMessage = new MQMessage();
gmo.Options = MQC.MQGMO_NO_WAIT;
mqQueue.Get(mqMessage, gmo);