1

我希望有人为我指出一些要求的正确方向:我们需要通过我们的服务器发送异步可靠通知消息的消费者将随意订阅/取消订阅消费者数量将很大生产者将是一个通知,即使服务器宕机,也不会丢失,如果服务器再次启动,将会发送通知。通知的数量预计会很高 使用的线程数应该尽可能低。

鉴于上述(疯狂的)要求,我尝试使用 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: Setting clientID on a used Connection is not allowed; 嵌套异常是 javax.jms.IllegalStateException: Setting clientID on a used Connection is not allowed

所以看来我不能使用使用 SimpleMessageListenerContainer 的持久订阅者进行会话,只能用于连接。这是真的?maxConnections=500 和 maximumActive=1 听起来合理吗?这解决了我的问题,但是……虽然对 JMS 来说是新手,但这对经纪人来说似乎有点过分了。

好的,考虑到我仍然在正确的轨道上,我现在需要动态地取消订阅我的消费者/听众,所以我这样做了

container.stop();
container.destroy();

其中容器是 SimpleMessageListenerContainer。容器.destroy(); 调用时抛出一些异常。是否有必要调用它或停止方法就足够了?

好的,我知道这些问题是武断的,即使对于知道 jms(如果 jms 是正确的解决方案)并且几乎没有从我的代码中给出任何内容的人来说,也可能很难回答。我希望有人给我一些指导,让我知道我是否在正确的轨道上,尽可能多地给我提出的问题,然后我可以在需要的地方提供代码,以解决我剩下的问题。

4

1 回答 1

1

我缺乏关于 spring 的知识来回答你关于 IllegalStateException 的问题,尽管我猜它与 maxConnections 设置为 10 有关。

你需要春天吗?在任何情况下,请确保您在 JMS 代理的配置中启用了持久性,确保使用持久队列/主题并确保setDurable(true)在消息上使用。

如果您想要可靠的消息传递,我认为您通常会做出正确的决定来使用功能强大的 JMS 提供程序。您可以使用 SPECjms2007 基准测试各种产品,具体取决于性能对您的重要性,也有一些可用的结果

于 2012-12-03T14:11:53.230 回答