JMS连接,会话和生产者/消费者之间的关系 [英] Relationship between JMS connections, sessions, and producers/consumers

查看:137
本文介绍了JMS连接,会话和生产者/消费者之间的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将一批20k JMS消息发送到同一队列。我正在使用10个线程分割任务,因此每个线程将处理2k个消息。我不需要交易。

I want to send a batch of 20k JMS messages to a same queue. I'm splitting the task up using 10 threads, so each will be processing 2k messages. I don't need transactions.

我想知道是否建议使用一个连接,一个会话和10个生产者?

I was wondering if having one connection, one session, and 10 producers is the recommended way to go or not?

如果我有一个生产者共享所有线程怎么样?我的邮件是否会损坏或是否会同步发送(不会带来任何性能提升)?

How about if I had one producer shared by all the threads? Would my messages be corrupt or would it be sent out synchronized (giving no performance gain)?

如果我决定是否创建新的连接或会话,那么通用指南是什么?总是连接到同一个队列?

What's the general guideline of deciding whether to create a new connection or session if I'm always connecting to the same queue?

谢谢你,并且很抱歉一次要求很多。

Thank you and sorry for asking a lot at once.

(这是一个类似的问题,但它并没有完全回答我的想法。长期存在的JMS会话。保持JMS连接/ JMS会话总是打开一个糟糕的实践吗?

(Here's a similar question, but it didn't quite answer what I was looking for. Long lived JMS sessions. Is Keeping JMS connections / JMS sessions allways open a bad pratice? )

推荐答案

如果某些邮件重复或丢失,可以吗?当JMS客户端通过网络连接到JMS代理时,任何API调用都有三个阶段。

Is it OK if some of the messages are duplicated or lost? When the JMS client connects to the JMS broker over the network there are three phases to any API call.


  1. API调用,包括任何消息数据,通过网络传输到代理。

  2. API调用由代理执行。

  3. 结果代码和任何消息数据是传回给客户。

考虑生产者一分钟。如果在第一步中断连接,则代理从未收到消息,应用程序需要再次发送。如果在第三步中连接断开,则消息已成功发送,再次发送将产生重复消息。应用程序无法区分这些,因此唯一安全的选择是重新发送错误消息。如果会话被处理,则可以在所有情况下安全地重新发送消息,因为如果原始消息已经发送到代理,它将被回滚。

Consider the producer for a minute. If the connection is broken in the first step then the broker never got the message and the app would need to send it again. If the connection is broken in the third step then the message has been successfully sent and sending it again would produce a duplicate message. The app cannot tell the difference between these and so the only safe choice is to resend the message on error. If the session is transacted the message can be safely resent in all cases because if the original had made it to the broker, it will be rolled back.

考虑消费者。如果在第三步中连接丢失,则消息将从队列中删除,但从未将其返回给客户端。但是,如果会话被处理,则在应用程序重新连接时将重新传递消息。

Consider the consumer. If the connection is lost in the third step then the message is deleted from the queue but never made it back to the client. But if the session is transacted the message will be redelivered when the application reconnects.

在交易之外,可能会丢失或重复消息。在事务内部存在相同的歧义窗口,但它在COMMIT调用而不是PUT或GET。通过事务处理会话,可以发送或接收消息两次但不会丢失一个消息。

Outside of transactions there is the possibility of lost or duplicate messages. Inside of a transaction the same window of ambiguity exists but it is on the COMMIT call rather then the PUT or GET. With transacted sessions it is possible to send or receive a message twice but not to lose one.

JMS规范识别出这种模糊性窗口,并提供以下指导:

The JMS spec recognizes this window of ambiguity and provides the following guidance:


如果
之间发生故障,则客户端在
a Session上提交工作的时间和提交方法
返回,如果事务已提交或
已回滚,则客户端无法确定
。当
非交易性发送PERSISTENT
消息与
发送方式返回之间发生故障时,存在相同的歧义

If a failure occurs between the time a client commits its work on a Session and the commit method returns, the client cannot determine if the transaction was committed or rolled back. The same ambiguity exists when a failure occurs between the non-transactional send of a PERSISTENT message and the return from the sending method.

由于这种模糊性,交易
需要JMS应用程序。在某些情况下,
这可能会导致客户产生
功能上重复的消息。

It is up to a JMS application to deal with this ambiguity. In some cases, this may cause a client to produce functionally duplicate messages.

由于
会话而重新传送的消息恢复不被视为
重复消息。

A message that is redelivered due to session recovery is not considered a duplicate message.

JMS会话应始终进行交易,除非它确实可以失去信息。如果会话是事务处理,那么由于JMS线程模型,您需要每个线程的会话和连接。

JMS sessions should always be transacted except for cases where it really is OK to lose messages. If the sessions are transacted then you'd need session and connection per-thread due to the JMS thread model.

有关性能影响的任何建议都是特定于供应商的,但是在API调用返回之前,将同步点之外的常规持久性消息强化为磁盘。但是,只要在COMMIT返回之前保留消息,就可以在将持久性消息写入磁盘之前返回事务调用。如果供应商基于此进行优化,那么将多个消息写入磁盘然后批量提交它会更高效。这允许代理通过磁盘块而不是按消息优化写入和磁盘刷新。放入交易的邮件数量随邮件大小的增加而减少,超过某个邮件大小会减少到一个。

Any advice about performance impacts would be vendor-specific but in general persistent messages outside of syncpoint are hardened to disk before the API call returns. But a transacted call can return before the persistent message is written to disk so long as the message is persisted before the COMMIT returns. If the vendor optimizes based on this, then it is much more performant to write several messages to disk and then commit them in batches. This allows the broker to optimize writes and disk flushes by disk block rather than per-message. The number of messages to put in the transaction decreases with the size of the message and beyond a certain message size dwindles back down to one.

如果您的20k邮件相对较小(以k而不是mb衡量)那么您可能希望每个线程使用事务处理会话并调整提交间隔。

If your 20k messages are relatively small (measured in k and not mb) then you probably want to use transacted sessions per thread and tune the commit interval.

这篇关于JMS连接,会话和生产者/消费者之间的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆