我希望有人指出我正确的方向来满足一些要求: 我们需要通过服务器发送异步可靠通知 消息的消费者将随意订阅/取消订阅 消费者数量众多 制片人将是一个 即使服务器出现故障,通知也不会丢失,如果服务器再次启动,则会发送通知。 通知数量预计会很高 使用的线程数应尽可能低。
鉴于上述(疯狂)要求,我尝试使用activemq / jms解决此问题。这看起来是正确的方向吗?
鉴于以上情况: 1.我使用持久订阅者和jms消息和kahadb。 2对于jms生产者来说,解决方案似乎很简单。 3.对于消费者方面,我遇到了麻烦。
一个。虽然我有春天,但我无法使用jms:listener-container,因为我需要动态订阅和取消订阅消费者,这似乎是不可能的,所以我为每个听众创建了一个SimpleListenerContainer。听起来不错? 湾在SimpleListenerContainer中,我设置了clientId(因为这是持久性所需的)
super.setSubscriptionDurable(durable);
if (durable ) super.setClientId(clientId);
在这里,我有以下内容。鉴于以下配置:
<bean id="messageBusReceiverConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="maxConnections" value="10"/>
<property name="maximumActive" value="500"/>
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="idleTimeout" value="0"/>
</bean>
我预计可能有10 * 500 = 5000个并行消费者。如果消费者不耐用,情况就是如此。但是,对于持久消费者,使用super.setClientId(clientId)(super是SimpleMessageListenerContainer),在第10次连接后,我得到: org.springframework.jms.IllegalStateException:不允许在已使用的Connection上设置clientID;嵌套异常是javax.jms.IllegalStateException:不允许在已使用的Connection上设置clientID
所以我似乎无法使用SimpleMessageListenerContainer为会话使用持久订阅者,仅用于连接。这是真的? maxConnections = 500和maximumActive = 1听起来合理吗?这解决了我的问题,但是......虽然JMS是新手,但对于经纪人来说这似乎有点过分了。
好的,考虑到我仍然在正确的轨道上,我需要现在取消订阅我的消费者/听众,动态地这样做
container.stop();
container.destroy();
其中container是SimpleMessageListenerContainer。 container.destroy();调用时抛出一些异常。是否有必要调用它或停止方法就足够了?
好的,我知道这些问题都是仲裁的,甚至对于知道jms的人来说也许很难回答(如果jms是正确的解决方案)并且我的代码几乎没有提供任何内容。我希望有人在我正确的轨道上给我一些指导,在提出的问题上尽可能多地给我输入,然后我可以在所需的地方提供代码以解决我剩下的问题。 / p>
答案 0 :(得分:1)
我缺乏关于spring的知识来回答关于IllegalStateException的问题,尽管我猜它与maxConnections设置为10有关。
你需要春天吗?在任何情况下,请确保在JMS Broker的配置中启用了持久性,确保使用持久的队列/主题,并确保在消息上使用setDurable(true)
。
如果您想要可靠的消息传递,我认为您通常会做出正确的决定,使用强大的JMS提供程序。您可以使用SPECjms2007基准测试各种产品,具体取决于性能对您的重要程度,还有一些results可用。