如果某些消息重复或丢失可以吗?当JMS客户端通过网络连接到JMS代理时,任何API调用都分为三个阶段。
- 包括任何消息数据在内的API调用都通过电线传输给代理。
- API调用由代理执行。
- 结果代码和任何消息数据将被发送回客户端。
考虑生产者一分钟。如果第一步断开连接,则代理将永远不会收到消息,应用程序将需要再次发送消息。如果在第三步中断开连接,则消息已成功发送,再次发送将产生重复消息。该应用无法分辨两者之间的区别,因此唯一安全的选择是在错误时重新发送消息。如果处理了该会话,则在所有情况下都可以安全地重新发送该消息,因为如果原始消息已发送给代理,它将被回滚。
考虑消费者。如果在第三步中丢失了连接,则会从队列中删除该消息,但永远不会将其发送回客户端。但是,如果进行了会话处理,则在重新连接应用程序时将重新发送该消息。
在交易之外,可能会丢失或重复发送消息。在事务内部,存在相同的歧义窗口,但它是在COMMIT调用上,而不是PUT或GET上。使用事务处理会话,可以发送或接收两次消息,但不会丢失一条消息。
JMS规范认识到这种歧义的窗口,并提供以下指导:
如果在客户端在会话上提交其工作到返回commit方法之间发生故障,则客户端无法确定事务是已提交还是已回滚。当在非事务性发送PERSISTENT消息与从发送方法返回之间发生故障时,存在相同的歧义。
由JMS应用程序来处理这种歧义。在某些情况下,这可能会导致客户端产生功能上重复的消息。
由于会话恢复而重新发送的消息不被视为重复消息。
除确实可以丢失消息的情况外,应始终进行JMS会话处理。如果会话是事务处理的,则由于JMS线程模型,您需要每个线程的会话和连接。
关于性能影响的任何建议都是特定于供应商的,但是通常,在API调用返回之前,同步点之外的持久性消息会被硬化到磁盘上。但是 ,只要持久消息在COMMIT返回
之前一直存在,事务处理调用就可以在将持久消息写入磁盘 之前返回
。如果供应商基于此进行优化,则将多个消息写入磁盘然后分批提交它们的性能要高得多。这使代理可以按磁盘块而不是按消息优化写入和磁盘刷新。放入事务中的消息数量随着消息的大小而减少,并且超过一定的消息大小会减少到一个。
如果您的20k消息相对较小(以k为单位,而不是以mb为单位),则您可能希望每个线程使用事务处理的会话并调整提交间隔。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)