我尝试使用以下代码验证同时使用异步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
}
}
慢十倍,这没有意义。
我在这里错过了什么吗?
putMessageOptions.Options = MQC.MQPMO_ASYNC_RESPONSE; //async
_queue.Put(_message, putMessageOptions); //send message asynchronously
更新1
Async Put
putMessageOptions.Options = MQC.MQPMO_SYNCPOINT; //unit of work
_queue.Put(_message, putMessageOptions);
_queueManager.Commit();
使用提交
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, sharey=True)
ax1.plot([-1, -1], [1, 1], linewidth=10, c="red")
sns.regplot(x=early_mean_zscore_untreated, y=late_mean_zscore_untreated, data=combo_untreated, ax=ax1, fit_reg=False)
sns.regplot(x=early_mean_zscore_treated, y=late_mean_zscore_treated, data=combo_treated, ax=ax2, fit_reg=False)
ax1.set(xlabel="Z-score for early PAs", ylabel="Z-score for late PAs")
ax2.set(xlabel="Z-score for early PAs", ylabel="Z-score for late PAs")
ax1.set(title="Resubmitted <= %d times" % resub_cutoff, aspect='equal')
ax2.set(title="Resubmitted > %d times" % resub_cutoff, aspect='equal')
fig.suptitle("Comparing improvement over the semester\nZ-scores")
ax1.plot([-1, -1], [1, 1], 'red', linewidth=10, )
plt.savefig("graphm.png")
plt.show()
Redhat Linux 7 +上的QueueManager版本:8.0.0.5
MQ.NET:8.0.0.8
答案 0 :(得分:0)
在IBM MQ v8知识中心页面&#34; Using asynchronous put in a client application&#34;它说:
通常,当应用程序将消息放入队列时, 使用MQPUT或MQPUT1,应用程序必须等待队列 经理确认已处理MQI请求。您可以 提高消息传递性能,特别是对于使用的应用程 客户端绑定和放置大量小的应用程序 消息到队列,通过选择放置消息 异步。当应用程序异步发送消息时, 队列管理器不会返回每次调用的成功或失败,但是 你可以定期检查错误。
Async put只影响put调用,它会立即返回而不是等待队列管理器确认它已经处理了put。
因此,如果你有以下内容,那么它将是最快的,因为你永远不会等待消息写入磁盘。
_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秒,那么我认为必定存在某种缺陷,我建议您与IBM打开PMR,他们可能会要求您至少客户端.NET跟踪和可能的队列管理器同时跟踪。