IBM MQ.NET отправляет сообщение асинхронно и фиксирует () - PullRequest
0 голосов
/ 29 апреля 2018

Я попытался проверить скорость использования async Put() и Commit(), используя код ниже. Проблема заключается в том, что его скорость в десять раз ниже, чем при использовании только async Put() или только Commit(), что не имеет смысла.

Я что-то здесь упускаю?

class AsyncProducerWithCommit 
    {
        private MQQueueManager _queueManager;
        private MQQueue _queue;

        public void Run()
        {
            Produce();
        }


        void Produce()
        {
            Open(ConnectionMode.Write);

            PutMessage(ConvertMessageToByte(message)); 

            _queue.Close();
            _queueManager.Disconnect();
        }

        void PutMessage(byte[] messageString)
        {          
            MQMessage _message = new MQMessage();
            _message.Write(messageString);
            _message.Format = MQC.MQFMT_STRING;
            _message.CharacterSet = 1208;// IbmUtf8Encoding;
            _message.Persistence = MQC.MQPER_PERSISTENT;

            var putMessageOptions = new MQPutMessageOptions();
            putMessageOptions.Options  =  MQC.MQPMO_SYNCPOINT    //unit of work
                                          + MQC.MQPMO_ASYNC_RESPONSE;  //async

            _queue.Put(_message, putMessageOptions); //send message asynchronously

             _queueManager.Commit();   

        }

        void Open(ConnectionMode connectionMode)
        {
            string _queueManagerName = _appSetting.MessagingServerSetting.QueueManagerName;

            int openOptions = 0;

            switch (connectionMode)
            {
                case ConnectionMode.Read:
                    openOptions = MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING;
                    break;
                case ConnectionMode.Write:
                    openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
                    break;
            }


            var properties = new Hashtable
            {
                {MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED },
                {MQC.CONNECT_OPTIONS_PROPERTY, MQC.MQCNO_RECONNECT },
                { MQC.HOST_NAME_PROPERTY, "192.168.1.10" },
                { MQC.PORT_PROPERTY, "1415"},
                { MQC.CHANNEL_PROPERTY, "LOCAL.DEF.SVRCONN" },
                {MQC.USER_ID_PROPERTY, "user" },
                {MQC.PASSWORD_PROPERTY, "pwd" }               
            };

            _queueManager = new MQQueueManager(_queueManagerName, properties);
            _queue = _queueManager.AccessQueue(QUEUE_NAME, openOptions);
        }


        public enum ConnectionMode
        {
            Read,
            Write
        }

    }

Обновление 1

Async Put

 putMessageOptions.Options  =  MQC.MQPMO_ASYNC_RESPONSE;  //async
_queue.Put(_message, putMessageOptions); //send message asynchronously

Положить с коммитом

 putMessageOptions.Options  =  MQC.MQPMO_SYNCPOINT;    //unit of work                                         
  _queue.Put(_message, putMessageOptions); 
 _queueManager.Commit(); 

Версия QueueManager: 8.0.0.5 в Redhat Linux 7 +

MQ.NET: 8.0.0.8

1 Ответ

0 голосов
/ 30 апреля 2018

На странице центра знаний IBM MQ v8 " Использование асинхронного ввода в клиентском приложении " указано:

Обычно, когда приложение помещает сообщение или сообщения в очередь, используя MQPUT или MQPUT1, приложение должно ждать очереди менеджер, чтобы подтвердить, что он обработал запрос MQI. Вы можете повысить производительность обмена сообщениями, особенно для приложений, которые используют клиентские привязки и приложения, которые помещают большое количество маленьких сообщения в очередь, выбрав вместо этого помещать сообщения асинхронно. Когда приложение помещает сообщение асинхронно, администратор очередей не возвращает успех или неудачу каждого вызова , но вместо этого вы можете периодически проверять наличие ошибок.

Асинхронный пут влияет только на вызов пут, который сразу же вернется, вместо того, чтобы ждать, пока администратор очередей подтвердит, что он обработал пут.

Так что, если у вас есть следующее, оно будет самым быстрым, так как вы никогда не будете ждать записи сообщения на диск.

_message.Persistence = MQC.MQPER_PERSISTENT;
putMessageOptions.Options  =  MQC.MQPMO_ASYNC_RESPONSE;  //async
_queue.Put(_message, putMessageOptions); //send message asynchronously

Если у вас есть какой-либо из них, фиксация будет ждать, пока сообщение не будет записано на диск, поэтому будет такой же медленной, как запись на диск. Вполне возможно, что это медленнее, чем выше, но 3 сек против 30 сек не кажется разумным.

_message.Persistence = MQC.MQPER_PERSISTENT;
putMessageOptions.Options  =  MQC.MQPMO_SYNCPOINT    //unit of work
                            + MQC.MQPMO_ASYNC_RESPONSE;  //async
_queue.Put(_message, putMessageOptions); //send message asynchronously
_queueManager.Commit();

Или

_message.Persistence = MQC.MQPER_PERSISTENT;
putMessageOptions.Options  =  MQC.MQPMO_SYNCPOINT;    //unit of work                                         
_queue.Put(_message, putMessageOptions); 
_queueManager.Commit(); 

Если вызов с MQPMO_SYNCPOINT и MQPMO_ASYNC_RESPONSE составляет 30 секунд, а вызов только с MQPMO_SYNCPOINT равен 3 секундам, то я думаю, что должен быть какой-то дефект, и я бы предложил вам открыть PMR с IBM, и они, вероятно, попросят вас по крайней мере, клиентская трассировка .NET и вероятная трассировка администратора очередей одновременно.

...