我有一个特定的要求,我需要将消息发送到一个永远不可用的服务器。
为此,我使用了一个特定于ActiveMQ的经纪人网络。
目标是拥有一个本地应用程序A(仅限生产者),它将消息推送到另一个中央应用程序B(仅限消费者)。然而,网络永远不可用。因此,应用程序的代理必须存储消息并等待连接才能向应用程序B发送消息。所以基本上A是需要在消息可用时将消息转发给B的代理
Broker的B配置包括一个持久的主题,它正在监听以消费消息。
正如在ActiveMQ documentation中所说的,我必须使用静态网桥来实现这一点,这就是我所做的。
注意:我无法订阅A,因为A会有多个实例,我无法在B中配置所有实例。
所以这是本地应用程序的配置(原始弹簧):
<!--As said in http://activemq.apache.org/spring-support.html use
a pooled conntection along with JMSTemplate -->
<amq:connectionFactory id="jmsFactory" brokerURL="${jms.broker.local.url}" />
<!--SpringJMSTemplate -->
<bean id="myJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsFactory" />
</bean>
<!-- local broker with embedded -->
<bean id="localbroker" class="org.apache.activemq.broker.BrokerService"
init-method="start" destroy-method="stop">
<property name="brokerName" value="localBroker" />
<property name="transportConnectorURIs">
<list>
<value>${jms.broker.local.url}</value>
</list>
</property>
<property name="networkConnectors">
<list>
<ref bean="networkConnector" />
</list>
</property>
</bean>
<amq:connectionFactory id="remoteJmsFactory"
brokerURL="${jms.broker.remote.url}" clientIDPrefix="BRIDGED-TEST" />
<bean id="networkConnector" class="org.apache.activemq.network.DiscoveryNetworkConnector">
<property name="uri" value="static:(${jms.broker.remote.url})"></property>
<property name="staticallyIncludedDestinations">
<list>
<bean class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg type="java.lang.String" value="${jms.topic.sample}"/>
</bean>
</list>
</property>
<property name="staticBridge" value="true"></property><!-- will deliver content even if no consumer, usefull for durable topic only -->
</bean>
localbroker是连接到远程代理的嵌入式代理(可以从apacheMQ页面下载的应用程序)。
这是中央配置
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:${activemq.conf}/credentials.properties</value>
</property>
</bean>
<bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
lazy-init="false" scope="singleton"
init-method="start" destroy-method="stop">
</bean>
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" useVirtualDestSubs="true">
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" >
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
</pendingMessageLimitStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<managementContext>
<managementContext createConnector="false"/>
</managementContext>
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
<transportConnectors>
<transportConnector name="http" uri="http://0.0.0.0:61612?maximumConnections=1000&wireFormat.maxFrameSize=10485760"/>
</transportConnectors>
<shutdownHooks>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
</shutdownHooks>
</broker>
<import resource="jetty.xml"/>
当我尝试发送/接收消息时发生了什么:
在网络连接器之前,我在本地代理配置中使用outboundTopicBridge尝试了jmsbridgeConnector而没有任何运气。
这是一个问题:我如何让本地经纪人A在重新连接时向中央经纪人B发送消息。虽然它不可用,但请确保他不会丢失任何信息。
注意:
答案 0 :(得分:0)
我一直在使用这种“存储转发”模式并成功使用网桥。
我无法评论网络连接器,但对于网桥,您必须:
org.apache.activemq.network.jms.ReconnectionPolicy
答案 1 :(得分:0)
我已经尝试过一直使用配置无法让它工作,所以我最终自己这样做了:
WKWebView
<jms:listener-container container-type="default" factory-id="proxyFactory"
acknowledge="transacted" destination-type="topic" connection-factory="jmsFactory">
基本上我只有一个订阅具有持久订阅的本地代理的类,并向远程发送消息,如果失败,则会回滚会话。
这个简单的代理依赖于Spring Listener的容器,因此即使他在远程代理上监听也可能工作,在我的情况下,它正在监听本地嵌入式代理,所以我不会有任何问题。 / p>
如果其他人在本地应用程序处于停止状态并且不需要重新启动来发送消息时停止/启动远程代理时只有其他配置应答,请随时发布,我将进行upvote并检查。< / p>
注意:您必须将<bean id="remoteJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="remoteJmsFactory" />
<property name="pubSubDomain" value="true"/>
</bean>
<bean id="simpleMessageProxyListener"
class="com.xxx.jms.test.SimpleMessageProxyListener">
<property name="jmsTemplate" ref="remoteJmsTemplate" />
<property name="queueName" value="${jms.topic.sample}" />
</bean>
设置为jms.redeliveryPolicy.maximumDeliveries
才能使其正常运行。