Java 使用JMS队列中的潜在陷阱?

Java 使用JMS队列中的潜在陷阱?,java,jms,message-queue,database,Java,Jms,Message Queue,Database,我被要求设计并实现一个系统,用于从大量设备接收大量自动传感器数据。这些数据将定期生成,并以http post中的xml格式发送到服务器。如果设备没有收到来自服务器的特定确认,它们将继续重新发送相同的数据。在通过事务将这些数据插入主数据库中的多个表之前,需要对这些数据进行一些可能很繁重的处理,此外,一些数据点需要排队以重新定向到其他外部URL 我计划使用Java应用服务器(倾向于GlassFish)和servlet来接收传入的数据。我想实现某种排队机制来临时存储数据,这样返回传感器的响应就不会依赖

我被要求设计并实现一个系统,用于从大量设备接收大量自动传感器数据。这些数据将定期生成,并以http post中的xml格式发送到服务器。如果设备没有收到来自服务器的特定确认,它们将继续重新发送相同的数据。在通过事务将这些数据插入主数据库中的多个表之前,需要对这些数据进行一些可能很繁重的处理,此外,一些数据点需要排队以重新定向到其他外部URL

我计划使用Java应用服务器(倾向于GlassFish)和servlet来接收传入的数据。我想实现某种排队机制来临时存储数据,这样返回传感器的响应就不会依赖于所有的中间处理。单独的独立队列也是数据重定向块的一个要求。在做了一些研究之后,两个主要的选择似乎是:

1) 在app server上安装数据库,并为各种队列使用表。队列将由Java应用程序处理,该应用程序可以运行在应用程序服务器中,也可以作为自己的服务独立运行

2) 使用数据库支持的JMS解决方案来实现队列

我对JMS不太熟悉,但从我所读到的内容来看,在这种情况下,它似乎是更好的解决方案。主要要求是,在处理传感器数据之前,不会丢失或丢弃队列中的传感器数据,并或多或少按顺序进行处理。我们还希望能够在某些时候轻松地停止对某些队列的处理,但仍然让它们积累数据,使这些消息永远不会自动过期

对于策略1,我很清楚如何满足这些需求,但它可能不如策略2健壮、可扩展,而且开发起来更复杂,因为我需要编写自己的多线程代码来处理各种独立队列。我想知道在使用JMS队列进行此用途时可能存在哪些潜在陷阱,因为我以前从未使用过它们

数据完整性是一个大问题,因此我需要确保JMS能够保证在服务器重新启动、断电或队列由于某种原因变得非常大的情况下不会丢失数据。例如,在一段时间内完成主数据库事务的问题可能会导致JVM内存不足、崩溃并丢失所有累积的数据吗?(这将是噩梦般的情景)


另外,我想知道是否有任何方法可以通过app server管理工具暂停JMS队列处理,或者轻松查看队列中的内容(我将使一个对象排队,该对象是消息xml加上一些其他数据,包括接收到的时间戳等)我在这里读过一些关于相关问题的帖子,但我想得到一些直接的反馈。基本上,我想知道JMS不是合适的队列解决方案的实例(如果有的话),以及这是否是其中之一。非常感谢您的建议。

如果您想选择JMS路线,那么一个独立的兼容JMS的消息代理(独立于您的应用服务器)将是一个不错的选择。消息代理的范围从免费的开源(如ActiveMQ at或OpenMQ at)到大规模的商业解决方案(IBM的WebSphere MQ at是最大的解决方案之一)

消息代理提供有保证的交付(前提是服务器已启动并正在侦听),您可以做很多工作来确保系统是故障安全的,包括集成的备份代理服务器和即时电源备份。如果你的应用服务器没有接收到消息,代理队列最终可能会耗尽空间,但你可以分配巨大的队列深度(100 GB),并让服务器在消息未得到处理且队列达到一定百分比时发送警报


然后,您的Java应用程序将在完全不同的服务器上运行,并将连接到代理并尽可能快地从队列中提取消息。如果应用程序服务器崩溃或由于任何其他原因停止接收消息,代理会将所有消息保留在该队列中,直到应用程序服务器再次开始接收它们。

Kaleb的回答非常雄辩地谈到了JMS的好处,但既然你问的是陷阱,下面是我能想到的

  • 并非所有JMS实现都是相同的。理论上,您可以使用任何适合您需要的实现,但除非您准备进行一些认真的负载测试和故障条件测试,否则您无法知道特定的实现在特定的用例下不会失败
  • 大多数JMS使用事务性数据存储(如关系数据库)作为后端。这意味着,与直接写入您熟悉的任何数据存储不同,您必须依赖JMS实现与存储消息之间的额外层
  • 虽然交换JMS实现以找到完全符合您需求的实现似乎是一项简单的工作,因为具有同质JMS API、故障处理的关键功能、JMS服务器监控、,如果您确实更改了实现,那么消息传递之外的所有其他很酷的东西都将是一件很麻烦的事情
也就是说,我认为您自己编写数据库而不是使用JMS是疯狂的。关于第一点,ActiveMQ是一个在许多企业环境中使用的久负盛名的JMS服务器。在第二点上,事实是,为了实现消息传递,您只需要自己编写额外的层,而您的代码将无法从成千上万的人(或者一组付费开发人员)的眼睛中获益,他们的唯一任务是响应客户并确保JMS实现是可靠的。在第三点上,后端数据存储也是如此。使用JMS,您将省去自己的麻烦