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

如何捕捉建立JMS连接的时间?

鲜于勇
2023-03-14

我有一些消息生产者正在使用ActiveMQ发送有关某些事件的JMS消息。但是,与ActiveMQ的连接可能不会一直处于关闭状态。因此,事件被存储,当建立连接时,它们被认为是读取和发送的。这是我的代码:

private void sendAndSave(MyEvent event) {
    boolean sent = sendMessage(event);
    event.setProcessed(sent);
    boolean saved = repository.saveEvent(event);
    if (!sent && !saved) {
        logger.error("Change event lost for Id = {}", event.getId());
    }
}

private boolean sendMessage(MyEvent event) {
    try {
        messenger.publishEvent(event);
        return true;
    } catch (JmsException ex) {
        return false;
    }
}

我想创建某种将在建立连接并处理未发送事件时调用的Application ationEventListener。我浏览了JMS、Spring框架和ActiveMQ留档,但找不到任何线索如何将我的侦听器与ConnectionFactory连接起来。

如果有人能帮我,我将不胜感激。

以下是我的应用程序Spring上下文对JMS的描述:

<!-- Connection factory to the ActiveMQ broker instance.              -->
<!-- The URI and credentials must match the values in activemq.xml    -->
<!-- These credentials are shared by ALL producers.                   -->
<bean id="jmsTransportListener" class="com.rhd.ams.service.common.JmsTransportListener" 
      init-method="init" destroy-method="cleanup"/>
<bean id="amqJmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="${jms.publisher.broker.url}"/>
    <property name="userName" value="${jms.publisher.username}"/>
    <property name="password" value="${jms.publisher.password}"/>
    <property name="transportListener" ref="jmsTransportListener"/>
</bean>

<!-- JmsTemplate, by default, will create a new connection, session, producer for         -->
<!-- each message sent, then close them all down again. This is very inefficient!         -->
<!-- PooledConnectionFactory will pool the JMS resources. It can't be used with consumers.-->
<bean id="pooledAmqJmsConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
    <property name="connectionFactory" ref="amqJmsConnectionFactory" />
</bean>

<!-- Although JmsTemplate instance is unique for each message, it is  -->
<!-- thread-safe and therefore can be injected into referenced obj's. -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <constructor-arg ref="pooledAmqJmsConnectionFactory"/>
</bean>

共有1个答案

易烨磊
2023-03-14

从您描述这个问题的方式来看,它听起来确实像一个开放和封闭的JMS持久订阅案例。在走这条路之前,您可能需要考虑一个更传统的实现。撇开注意事项不谈,ActiveMQ提供了您可以收听的咨询消息,这些消息将被发送给各种事件,包括新连接。

=========

糟糕,对不起...我不明白问题是什么。我认为咨询根本不是解决方案......毕竟,你需要连接到经纪人才能得到它们,但连接是你所知道的。

如果我理解正确(准备重试#2….),您需要的是一个客户端连接,当它失败时,会尝试无限期地重新连接。当它重新连接时,您希望触发一个(或更多)事件,将挂起的消息刷新到代理。

所以检测丢失的连接很容易。您只需注册一个JMS ExceptionListener。至于检测重新连接,我能想到的最简单的方法是启动一个重新连接线程。当它连接时,停止重新连接线程,并使用观察者/观察者或JMX通知等通知相关方。您可以使用ActiveMQ故障转移传输,它将为您执行连接重试循环,即使您只有一个代理。至少,它应该这样做,但它不会为你做那么多,而你自己的重新连接线程不会这样做...但是如果你愿意将一些控制权委托给它,它会缓存你未刷新的消息(参见trackMessages选项),然后在重新连接时发送它们,这就是你正在尝试做的事情。

我想如果你的经纪人停机几分钟,这是一个不错的方法,但是如果你在谈论几个小时,或者你可能会在停机时间积累10k消息,我只是不知道这种缓存机制是否像你需要的那样可靠。

==================

移动应用程序。。。正当不太适合故障转移传输。然后,我将实现一个定期连接的计时器(使用http传输可能是个好主意,但并不相关)。当它连接时,如果没有什么需要刷新的,那么x分钟后见。如果有的话,发送每条消息,等待握手,然后从你的移动商店中清除消息。那么x分钟后再见。

我猜这是Android?如果没有,请停止阅读。实际上,我们在一段时间前就实现了这一点。我只做了服务器端,但如果我没记错的话,连接计时器/轮询器每n分钟旋转一次(我认为频率可变,因为太过激进会耗尽电池)。一旦建立了成功的连接,我相信他们使用了意图广播来推动消息推送者做他们的事情。我们的想法是,即使只有一个消息推送器,我们也可以添加更多。

 类似资料:
  • 我正在建造我的第一个Java图书馆。代码使用了大量的IO方法,因此可以想象有大量的异常需要捕获。但我在想,我应该抛出例外吗?我的意思是,捕捉异常当然是应用程序编写者的工作。因为即使我抓到了它们,我也不知道应用程序在发生这种情况时会做什么。 我应该抛出IOExceptions等,还是应该在库代码中捕获它们?

  • 我的会监听局域网连接并很好地接受它们,但当我试图通过手机连接到同一个网络时(使用3G连接),它似乎无法连接。 > 我尝试使用站点获取并尝试连接到它,它确实得到正确的(用我的路由器检查),但然后没有连接被接受。 我试着打开windows 7和路由器上的端口。 我把这些行在我的服务器构造函数: 我将主机上的ip设置为0.0.0.0 谢谢你的帮助。

  • 问题内容: 我试图理解,我在我的应用程序中使用。我在中编写了以下代码: 我在Windows Xp OS中将4型jdbc连接与oracle 10g EE一起使用 然后我按如下方式检索servlet: 是它还是需要某些配置? 问题答案: 您可以获得第三方库,也可以使用连接池为您提供的Java EE容器(例如,JBoss或WebSphere)。 为此,您可以配置和使用JNDI数据源。 以下是Tomcat

  • 问题内容: 谁能推荐一些在python中建立ssh连接的东西?我需要它与任何操作系统兼容。 我已经尝试使用pyssh来获取SIGCHLD的错误,我读过这是因为Windows缺少此错误。我尝试过使paramiko正常工作,但是在paramiko和Crypto之间存在错误,以至于每个版本的最新版本都无法协同工作。 Windows计算机上当前使用Python 2.6.1。 问题答案: 请注意,这在Win

  • 在节点中。在js服务器上,捕获SIGTERM和捕获SIGINT有什么区别吗? 我认为进程不应该能够防止SIGINT关闭? 我是否能够捕获两个信号并阻止退出?我的实验表明答案是肯定的,但从我所读到的内容来看,SIGINT总是假设关闭一个进程。 或者我把SIGINT和SIGKILL混淆了?也许SIGKILL是我无法恢复的信号? 捕捉这些信号当然可以让我优雅地关机: 我想我把SIGINT和SIGKILL

  • 问题内容: 我有一个很大的数学表达式,必须动态创建。例如,一旦我已经解析了“东西”,结果就会像一个字符串:。 因此,为了计算该表达式的结果,我使用的是函数…… 这里的问题是,有时我会收到错误消息,说被零除,并且我不知道如何捕获该异常。我已经尝试过类似的事情: 要么: 但这行不通。因此,如何避免被零除的应用程序崩溃? 编辑: 首先,我想澄清一下:表达式是动态构建的,因此如果分母为零,我不能仅仅求值。