Spring提供了一个JMS集成框架,简化了JMSAPI的使用。消息监听器是JMS应用程序的一部分。为了异步接收JMS消息,Spring 提供了一个创建消息驱动的POJO(MDP)的解决方案。
Spring MessageListenerContainer允许我们在没有EJB容器的情况下注册MessageListeners。它被用来异步地接收消息。它是Pojo和消息提供者之间的中间人。它从队列中轮询消息并将其反馈给监听器。
两个与Spring打包的标准JMS MessageListenerContainer是。DefaultMessageListenerContainer(DMLC)和SimpleMessageListenerContainer(SMLC)。
这两个容器的细节和方法都可以在这里查看。我特别要写的是在创建JMS应用程序时的区别和面临的问题。
SimpleMessageListenerContainer使用推式方法,而DefaultMessageListenerContainer则使用拉式方法,这基本上意味着它坐在一个无限的循环中接收消息。
SMLC是消息监听器容器的最简单形式。它创建固定数量的JMS会话来调用监听器,并且不允许任何运行时需求。它的主要优点是复杂程度低,对JMS提供者的要求最低。
虽然SMLC使用起来很简单,而且是本地JMS的首选,如果JMS提供者能优雅地处理线程管理和连接恢复,它也有一些缺点。
特别是当你的队列/主题与你的监听器不在同一台服务器上,或者与JMS提供者经常发生连接失败时,线程管理将是SMLC的主要问题,因为一旦你的监听器被启动,线程数超过该服务器的极限,它就会继续创建不必要的线程,因为Linux 有一个每个用户允许的最大进程限制,这可能导致应用程序出现错误**(无法创建新的本地线程:内存不足问题**)。
你将需要重新启动你的应用程序以杀死所有的线程,这将偏离使用MessageListenerContainer持续监听消息的整个目的。
上述问题的解决方案是,在这种情况下应该使用DMLC,而且在许多环境中也是一种更值得推荐的方法。它不使用/阻止JMS提供者线程。它还能优雅地处理连接失败。
深入了解一下,我有一个带有JMS实现的应用程序。最初,在JMS提供者被托管在本地服务器上之前,使用SMLC工作得很好。
后来,提供者被转移到AWS的设置中,并有一些常见的连接重置,这开始导致线程问题。在我用 DefaultMessageListenerContainer替换了我的SimpleMessageListenerContainer 之后,这个问题得到了解决 。
在这篇文章中,我们看了Spring 提供的两种不同的JMS监听器以及它们的用法。我希望你觉得这篇文章很有用。
谢谢!
JMS -SimpleMessageListenerContainer Vs DefaultMessageListenerContainer最初发表在Medium上的Javarevisited,人们通过强调和回应这个故事来继续对话。