【发布时间】:2012-12-03 22:11:53
【问题描述】:
我希望有人为我指出一些要求的正确方向: 我们需要通过我们的服务器发送异步可靠通知 消息的消费者将随意订阅/取消订阅 消费者数量将很大 制作人将是一个 即使服务器关闭,通知也不会丢失,如果服务器再次启动,将发送通知。 预计通知数量会很高 使用的线程数应尽可能少。
鉴于上述(疯狂的)需求,我尝试使用 activemq/jms 来解决这个问题。这看起来是正确的方向吗?
鉴于上述情况: 1. 我使用了持久订阅者和 jms 消息和 kahadb。 2 对于 jms 生产者,解决方案似乎很简单。 3.对于消费者来说,我有麻烦了。
一个。虽然我有 spring,但我不能使用 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 is SimpleMessageListenerContainer) 的持久消费者,在第 10 次连接后,我得到: org.springframework.jms.IllegalStateException:不允许在使用的连接上设置 clientID;嵌套异常是 javax.jms.IllegalStateException: Setting clientID on a used Connection is not allowed
所以看来我不能使用使用 SimpleMessageListenerContainer 进行会话的持久订阅者,只能用于连接。这是真的? maxConnections=500 和 maximumActive=1 听起来合理吗?这解决了我的问题,但是……虽然对 JMS 来说是新手,但这对代理来说似乎有点过头了。
好的,考虑到我仍然在正确的轨道上,我现在需要动态取消订阅我的消费者/听众,所以我这样做了
container.stop();
container.destroy();
其中容器是 SimpleMessageListenerContainer。容器.destroy();调用时抛出一些异常。是需要调用还是stop方法就够了?
好的,我知道这些问题是武断的,即使对于知道 jms(如果 jms 是正确的解决方案)并且几乎没有从我的代码中给出任何内容的人来说,也可能难以回答。我希望有人能给我一些指导,让我知道我是否走在正确的轨道上,尽可能多地给我提出的问题,然后我可以在需要的地方提供代码,以解决我剩下的问题。
【问题讨论】:
-
复杂的问题?太宽泛而无法通过一篇文章来回答?愚蠢的问题?这么长时间以来,我不太习惯于堆栈溢出来回答问题。我已经按照上面提到的 JMS 完成了它,所以我想这个问题不再是紧急的,或者不再是我这边的问题了。但是,如果有人希望对我的做法提供一些支持,请告诉我,我可以分享一些信息。我不确定我是否遵循了最好的方法。
-
解决了吗?