当前位置: 首页 > 知识库问答 >
问题:

JMS持久异步事件通知

微生阳平
2023-03-14

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

鉴于上述(疯狂的)要求,我试图使用activemq / jms来解决这个问题。这似乎是正确的方向吗?

考虑到以上:1.我使用了持久订阅者、jms消息和kahadb。2对于jms生产者,解决方案似乎是直截了当的。3.在消费者方面,我遇到了麻烦。

一个。虽然我有Spring,但我不能使用jms:listener-container,因为我需要有消费者的动态订阅和取消订阅,这似乎是不可能的,所以我为我拥有的每个听众创建一个简单的听众容器。这听起来还行吗?b.在简单列表容器中,i设置客户端Id(因为这是持久化所需的)

    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)(超级是SimpleMessageListenerContainer)的情况下,在第10个连接后,我得到:org.springframework.jms.IllegalStateException:不允许在已使用的连接上设置clientID;嵌套异常是javax.jms.IllegalStateException:不允许在已使用的连接上设置clientID

因此,我似乎无法使用使用SimpleMessageListenerContainer的持久订户进行会话,而只能用于连接。这是真的吗?maxConnections=500和maximumActive=1听起来合理吗?这解决了我的问题,但是……虽然JMS是新的,但对于代理来说,这似乎是过火了。

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

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

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

好吧,我知道这些问题是任意的,甚至对于了解jms(如果jms是正确的解决方案)并且几乎没有从我的代码中得到任何东西的人来说,也可能很难回答。我希望有人能就我是否在正确的轨道上给我一些指导,尽可能多地就所提出的问题给我输入,然后我可以在需要的地方给出代码,以解决我剩下的问题。

共有1个答案

施雅懿
2023-03-14

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

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

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

 类似资料:
  • 我得到警告“这个异步方法缺少'await'运算符,将同步运行。考虑使用'await'运算符来等待非阻塞API调用,或者使用'await task.run(...)‘来在后台线程上执行CPU绑定的工作。虽然这听起来很明显,但我认为我已经被覆盖了,因为我运行所有进程,并在我的processFiles方法中有一个await任务。Whenall()。我需要用不同的方式来做这件事吗?如果有任何想法,我将不胜

  • 我正在使用网络逻辑10.3。我正在尝试配置一个持久订阅,其中包含由 jdbc 存储(在 Oracle DB 中)支持的持久消息。我有一个主题,MDB 正在作为持久订阅者侦听该主题。在场景-1下:如果我发送消息,它会命中MDB。 在场景2中:我挂起了MDB,希望发送到主题的消息只要不被MDB(它是唯一注册的持久订阅者)使用,就会一直存在。但是当我向主题发送消息时,它短暂地出现在那里,然后就消失了(我

  • 我试图从azure服务总线主题异步读取消息。我根据MS文档创建了JMS监听器 我需要确保topicJmsListenerContainerFactory容器工厂是否支持异步处理? 我尝试像下面这样实现DefaultJmsListenerContainerFactory,但是使用它我无法从服务总线顶部获取任何消息。它引发了一个异常,无法找到消息传递实体。我可以使用topicJmsListenerCo

  • 调用init方法失败;嵌套的异常是javax。坚持不懈PersistenceException:[PersistenceUnit:默认值]无法生成Hibernate SessionFactory 在更换系统中的操作系统后,我遇到了这个异常。在我的应用程序运行MySQL 5.7和java 8之前。现在我把它改成了mySQL 8和java 8。代码没有任何变化。原因一定是什么?? 下面是日志:

  • 我有一个UserControl上的事件,我正在听: 具有以下签名: 在以下情况下,如何调用此异步方法: 不阻塞GUI线程 在调用我的异步方法后能够调用 能够在正确的(GUI)线程中调用。 我所尝试的: -- -- --

  • 然后,在发现步骤之后,它注册方法。 查看由JBoss Weld2提供的方法,我看到: 那么我的问题是,这些方法不会被调用两次吗?我的意思是,它们可能被注册两次,首先通过容器本身,然后通过调用方法。