JMS连接,会话和生产者/使用者之间的关系

Rus*_*ell 42 java jms

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

我想知道是否有一个连接,一个会话和10个生产者是否是推荐的方式?

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

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

谢谢你,很抱歉一下子就问了很多.

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

T.R*_*Rob 28

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

  1. API调用(包括任何消息数据)通过线路传输到代理.
  2. API调用由代理执行.
  3. 结果代码和任何消息数据都将传输回客户端.

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

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

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

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

如果客户端在会话上提交其工作并且提交方法返回之间发生故障,则客户端无法确定事务是已提交还是已回滚.当PERSISTENT消息的非事务性发送与发送方法的返回之间发生故障时,存在相同的歧义.

由JMS应用程序来处理这种模糊性.在某些情况下,这可能会导致客户端生成功能上重复的消息.

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

除了可以丢失消息的情况外,应始终对JMS会话进行处理.如果会话是事务处理,那么由于JMS线程模型,您需要每个线程的会话和连接.

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

如果您的20k消息相对较小(以k而不是mb为单位),那么您可能希望每个线程使用事务处理会话并调整提交间隔.


小智 9

在大多数情况下,使用一个连接和多个会话就足够了,每个线程使用一个会话.在某些环境中,您可以通过使用多个连接获得额外的性能:

某些消息传递系统支持群集模式,其中连接被负载平衡到不同的节点.通过多个连接,您可以在此方案中使用多个节点的性能.(当瓶颈位于消息代理的一侧时,这当然只有帮助).

最好的解决方案是给我们一个连接池,并为管理员提供一些选项来配置特定区域中的行为.