IBM MQ.NET 异步发送消息并提交()

IBM MQ.NET Send Message Asynchronously and Commit()

我尝试使用下面的代码验证同时使用异步 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

异步放置

 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 版本:Redhat 上的 8.0.0.5 Linux 7+

MQ.NET: 8.0.0.8

在 IBM MQ v8 知识中心页面“Using asynchronous put in a client application”中指出:

Normally, when an application puts a message or messages on a queue, using MQPUT or MQPUT1, the application has to wait for the queue manager to confirm that it has processed the MQI request. You can improve messaging performance, particularly for applications that use client bindings, and applications that put large numbers of small messages to a queue, by choosing instead to put messages asynchronously. When an application puts a message asynchronously, the queue manager does not return the success or failure of each call, but you can instead check for errors periodically.

异步放置只影响放置调用,它会立即 return 而不是等待队列管理器确认它已经处理了放置。

因此,如果您有以下内容,那么它应该是最快的,因为您永远不会等待消息写入磁盘。

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

如果您有其中任何一个,提交将等待消息写入磁盘,因此速度将与磁盘写入速度一样慢。这很可能比上面的慢,但是 3sec vs 30sec 似乎不合理。

_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 秒,那么我认为一定存在某种缺陷,我会建议您打开 IBM 的 PMR,他们可能会同时要求您至少提供客户端 .NET 跟踪和可能的队列管理器跟踪。