【发布时间】:2012-01-20 14:55:47
【问题描述】:
环境
- 已有软件采用专有的集群方式,应移至使用JMS
- 客户不想为设置和维护一个 消息传递系统,因此只有在我可以嵌入整个系统的情况下才能使用它 向现有虚拟机发送消息
- 代理实例和消费者应该在同一个 JVM 中。消费者 应该能够在故障转移情况下连接到远程代理,因为所有消费者,无论他们将在哪个 JVM 中运行,都应该有一个输入队列。
- 如果消费者使用直接方法调用来 与当地经纪人沟通
演示项目
我用 ActiveMQ + Maven + Spring 创建了一个非常简单的演示(eclipse)项目(整个项目位于http://www.woofiles.com/dl-279452-fOcsWkcm-activemq.zip)。如果你试试,把activemq的dataDirectory改一下,因为到现在都是有线的绝对路径。
我尝试从 spring 启动一个代理,以及一组消费者。请参阅下面的 Spring 配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" />
</bean>
<bean id="embeddedBroker" class="org.apache.activemq.broker.BrokerService"
destroy-method="stop" init-method="start" >
<property name="brokerName" value="conversion" />
<property name="dataDirectory"
value="c:\eclipseWithMaven\activemq\working\conversion" />
<property name="schedulerSupport" value="false" />
<property name="transportConnectorURIs">
<list>
<value>tcp://127.0.0.1:600${idOfClusterNode}</value>
</list>
</property>
<property name="managementContext">
<bean class="org.apache.activemq.broker.jmx.ManagementContext">
<property name="connectorPort" value="201${idOfClusterNode}" />
</bean>
</property>
</bean>
<!-- depends-on see why at http://activemq.apache.org/vm-transport-reference.html -->
<!--depends-on="embeddedBroker" -->
<bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory" depends-on="embeddedBroker">
<property name="brokerURL">
<value>failover:(vm:/conversion,tcp://127.0.0.1:6001,tcp://127.0.0.1:6002)</value>
</property>
</bean>
<bean id="cachedConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory"
p:targetConnectionFactory-ref="jmsFactory" p:sessionCacheSize="10" />
<bean id="container"
class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="concurrentConsumers" value="10" />
<property name="connectionFactory" ref="cachedConnectionFactory" />
<property name="messageListener" ref="conversion" />
<property name="destination" ref="conversionInputQueue" />
</bean>
<bean id="conversionInputQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="conversionInputQueue" />
</bean>
<bean id="conversion" class="activemq.Conversion"
p:clusterId="${idOfClusterNode}" />
</beans>
我只是尝试使用 spring 和 log4j 配置使用的不同参数启动一个或两个 activemq.ConversionDemo 类实例。运行配置的环境条目如下所示:
- 实例 1:-DidOfClusterNode=1 -DidOfOtherClusterNode=2 -DlogFile=conversion1.log
- 实例 2:-DidOfClusterNode=2 -DidOfOtherClusterNode=1 -DlogFile=conversion2.log
如果我启动一个实例,那很好。如果两个运行时出现以下问题:
- 第二个代理根本不会启动。它说它没有锁。它很好,但我想,它只是异步启动一个线程,并将控制权交还给 spring。但它似乎不会让春天继续下去。
- SimpleMessageListenerContainer 似乎也像持有控制权 整个春天,直到所有消费者都开始。
我想要什么
- 我想满足以上要求
- 我想我必须异步启动代理和消费者, 我不能在春天用这个配置真正做到这一点
- 在代理之间进行真正的负载平衡会很好。看来,ActiveMQ 只为故障转移做好了准备。
- 如果ActiveMQ不能满足我的需求,请推荐 其他免费解决方案。
如果您需要更多信息,请告诉我。
编辑
我认为 ActiveMQ 支持我的需求,我只需要了解“代理网络”。所以我想我必须有两个文件存储和一个来自我的两个代理的网络。
【问题讨论】:
-
您真的需要经纪人网络吗?您是否需要多个代理供您的消费者连接,或者您需要其中两个仅用于故障转移?
标签: spring activemq cluster-computing