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

标签 c# ibm-mq

我尝试使用下面的代码验证同时使用异步 Put()Commit() 的速度。问题是它的速度比仅使用异步 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 Linux 7+ 上的 8.0.0.5

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.

Async put 只影响 put 调用,它会立即返回,而不是等待队列管理器确认它已经处理了 put。

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

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

如果你有其中任何一个,提交将等待消息写入磁盘,因此将与磁盘写入一样慢。这很可能比上面的慢,但 3 秒 vs 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 秒,那么我认为一定存在某种缺陷,我建议您打开 IBM 的 PMR,他们可能会要求您提供至少一个客户端 .NET 跟踪和可能的队列管理器跟踪。

关于c# - IBM MQ.NET 异步发送消息并提交(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50091245/

相关文章:

ibm-mq - IBM MQ Client 9.0 在 Window 7 Professional SP1 上安装失败

c# - 根据键获取列表List<T>中的自定义对象T

c# - 要么或要求验证

c# - 从 C# MongoDb 启用分片

c# - 由于特殊字符,在 VB.Net 中解析 XML 失败

c# - 从双二维数组创建位图

sql-server-2012 - SQL Server 和 Websphere MQ 的分布式事务

java - 通过来自 Java 的 PCF 请求获取连接到 IBM MQ 队列的消费者的 ip

java - 我发送到队列的 SOAP 请求在 IBM MQ 上格式不正确

jndi - 无法通过JNDI与Websphere MQ SSL channel 连接