Я пытаюсь заставить MQ v6 сегментировать сообщения, используя флаг сообщения MQMF_SEGMENTATION_ALLOWED и опцию сообщения put MQPMO_LOGICAL_ORDER, как это предлагается в справочном руководстве IBM.
ImqMessage message;
message.setFormat(MQFMT_STRING);
message.setMessageFlags(MQMF_LAST_MSG_IN_GROUP | MQMF_SEGMENTATION_ALLOWED);
/* ... */
ImqPutMessageOptions pmopts;
pmopts.setOptions(MQPMO_LOGICAL_ORDER);
if (!queue.put(message, pmopts))
{
buflen;
m_iLastError = queue.reasonCode();
CString reason;
reason.Format(_T("%d"), queue.reasonCode());
_errorMsg = "Reason code: " + reason;
/* throw exception etc.. */
}
Независимо от того, задаю ли я эти флаги, когда я вызываю put (), он всегда возвращает false и имеет код причины (2010) MQRC_DATA_LENGTH_ERROR.
Существуют ли какие-либо распространенные ошибки, связанные с v6 и сегментацией (например, они недоступны в Windows, что-то наподобие этого) … или какие-либо предложения, которые стоит попробовать?
Извиняюсь за слегка неконтекстный пример кода. Я постараюсь ответить на вопросы, которые есть у людей о моей проблеме, как можно лучше.
Хорошо, я нашел решение этой конкретной ошибки: сообщение, которое больше, чем максимальная длина сообщения канала не будет помещен в очередь независимо от того, может ли сообщение быть сегментировано или максимальный размер сообщения, разрешенный администратором очередей и очередей.
Установка максимального размера сообщения на канале не может быть выполнена исключительно путем вызова ImqChannel::maximumMessageLength()
, В командной строке необходимо изменить конфигурацию:
Войти runmqsc YOUR_QUEUE_MANAGER_NAME
В командной строке проверьте максимальную длину сообщения существующего канала (в версии 6 значение по умолчанию составляет 4 МБ):
display channel(CHANNEL_NAME)
Вы получите что-то вроде
CHANNEL(SYSTEM.DEF.SVRCONN) CHLTYPE(SVRCONN)
ALTDATE(2013-07-12) ALTTIME(09.57.15)
COMPHDR(NONE) COMPMSG(NONE)
DESCR( ) HBINT(300)
KAINT(AUTO) MAXMSGL(4194304) <- max length, obvs ;-)
MCAUSER( ) MONCHL(QMGR)
RCVDATA( ) RCVEXIT( )
SCYDATA( ) SCYEXIT( )
SENDDATA( ) SENDEXIT( )
SSLCAUTH(REQUIRED) SSLCIPH( )
SSLPEER( ) TRPTYPE(TCP)
Чтобы увеличить размер:
alter channel(CHANNEL_NAME) CHLTYPE(SVRCONN) MAXMSGL(104857600)
для 100 МБ
Теперь вам нужно установить значение канала в коде, используя ImqChannel::maximumMessageLength(104857600)
или он будет использовать по умолчанию 4 МБ. MAXMSGL будет иметь приоритет над этим вызовом, поэтому передача значения> MAXMSGL не будет иметь никакого эффекта.
Теперь, когда вы звоните put()
любое сообщение без сегментации вызовет ошибку 2030 (MQRC_MSG_TOO_BIG_FOR_Q) или 2031 (MQRC_MSG_TOO_BIG_FOR_Q_MGR). При сегментации сообщение теперь должно быть разделено, а сегменты помещены в очередь.
Надеюсь, это поможет кому-то!
Других решений пока нет …