在Spring-MVC Tomcat webapp中嵌入ActiveMQ代理

时间:2010-08-18 14:23:16

标签: spring tomcat spring-mvc jms activemq

我有一个小型的Spring MVC webapp(嵌入ActiveMQ),旨在在本地Tomcat中运行,并可靠地向远程ActiveMQ上的队列发送消息。

除了“可靠”之外,所有这些都已到位。目前,如果远程站点出现故障,则发送失败。我的发送配置:

<!-- Connection setup -->
<bean id="connectionFactory" 
    class="org.apache.activemq.ActiveMQConnectionFactory" 
    p:brokerURL="tcp://backend-server-box:61616" />

<bean id="cachedConnectionFactory" 
    class="org.springframework.jms.connection.CachingConnectionFactory"
    p:targetConnectionFactory-ref="connectionFactory" 
    p:sessionCacheSize="10" />

<!-- Bean that represents the correct destination on the backend server -->
<bean id="backendDestination" class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-arg value="jmsQueueName" />
</bean>

<bean id="backendTemplate" 
    class="org.springframework.jms.core.JmsTemplate"
    p:connectionFactory-ref="cachedConnectionFactory"
    p:defaultDestination-ref="backendDestination" />

<!-- Bean that sends to the correct destination on the backend server -->
<bean id="simpleSender" class="uk.co.mycompany.client.messaging.SimpleSender">
    <property name="jmsTemplate" ref="backendTemplate" />
</bean>

我认为我需要的是一个本地的,持久的代理,即connectionFactory(上面定义的第一个bean)所指向的,它知道远程代理(JMS到JMS桥吗?)如果有一些明确的文档到处理这个问题我很高兴能够指出它,但我不得不把事情拼凑在一起,主要来自非常有帮助的BruceBlog。或者任何直接的帮助都会很棒。

由于

<击>的更新即可。一些修正:

    <击>
  1. Eclipse没有正确找到amq命名空间。 This是你发现原因被破坏的地方,这是一个简单的解决方法。
  2. 正如Miklos在下面的评论中所说,你需要在webapp lib中使用org.osgi.core-4.1.0.jar。从ActiveMQ lib / optional文件夹中获取。
  3. 您还需要Apache Commons xbean-spring-3.4.jar。得到它here
  4. This指南让我度过了接下来的几个障碍。这是完美的,除了在几个地方属性名称不正确(brokername应该是brokerName,而physicalname应该是physicalName)。
  5. 更新2 。我已经在下面正确回答了。不需要任何amq的东西!

2 个答案:

答案 0 :(得分:8)

这是怎么做的。

假设

  1. 您正在 http://destination-box:61616
  2. 上连接到远程目标
  3. 您将通过VM transport vm:// localhost:7001
  4. 上与本地经纪商联系
  5. 您要连接两个远程队列: queue1 queue2
  6. Pre:名称空间

    您需要声明以下命名空间:

    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:jms="http://www.springframework.org/schema/jms"
    

    1。创建本地经纪人:

    <bean id="bridgedBroker" class="org.apache.activemq.broker.BrokerService"
     init-method="start" destroy-method="stop">
      <property name="brokerName" value="bridgedBroker"/>
      <property name="persistent" value="true"/>
      <property name="transportConnectorURIs"> 
        <value>vm://localhost:7001</value>
      </property>
      <property name="jmsBridgeConnectors">
        <bean class="org.apache.activemq.network.jms.JmsQueueConnector">
          <property name="outboundQueueConnectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
              <property name="brokerURL" 
               value="failover:(tcp://destination-box:61616)?maxReconnectDelay=10" />
            </bean>
          </property>
          <property name="outboundQueueBridges">
            <list>
              <bean class="org.apache.activemq.network.jms.OutboundQueueBridge">
                <constructor-arg value="queue1"/>
              </bean>
              <bean class="org.apache.activemq.network.jms.OutboundQueueBridge">
                <constructor-arg value="queue2"/>
              </bean>
            </list>
          </property>
        </bean>
      </property>
    </bean>
    

    因此,您正在使用持久性,由属性激活,以及Broker Configuration URI来配置重试行为。您必须在 outboundBridgeQueues 列表中列出要连接的每个远程队列的名称。

    2。创建代理连接工厂

    这个连接到上面的经纪人:

    <bean id="brokerConnectionFactory"
     class="org.apache.activemq.ActiveMQConnectionFactory"
     p:brokerURL="vm://localhost:7001" />
    

    然后用CachingConnectionFactory(几乎总是good idea)包装它:

    <bean id="cachingBrokerConnectionFactory"
     class="org.springframework.jms.connection.CachingConnectionFactory"
     p:targetConnectionFactory-ref="brokerConnectionFactory"
     p:sessionCacheSize="10" />
    

    3。创建远程目标的本地等效项

    您现在要与之交谈的每个目的地都需要本地代表:

    <bean id="queue1destination" class="org.apache.activemq.command.ActiveMQQueue">
      <constructor-arg value="queue1" />
    </bean>
    
    <bean id="queue2destination" class="org.apache.activemq.command.ActiveMQQueue">
      <constructor-arg value="queue2" />
    </bean>
    

    4。创建要连接到本地bean的JMS模板

    我会在这里为 queue1 制作一个; queue2 是完全相同的过程:

    <bean id="queue1JMSTemplate"
     class="org.springframework.jms.core.JmsTemplate"
     p:connectionFactory-ref="cachingBrokerConnectionFactory"
     p:defaultDestination-ref="queue1destination" />
    

    5。使用JMS模板

    一些示例代码:

    public class SendToQueue1
    {
      @Autowired protected JmsTemplate queue1JMSTemplate; 
    
      public void sendMessage(final String message) throws JMSException
      {
        queue1JMSTemplate.send(new MessageCreator()
        {
          public Message createMessage(Session session) throws JMSException
          {
            return session.createTextMessage(message);
          }
        });
      }
    }
    

    你已经完成了!实际上并不太痛苦,但需要一段时间才能让它运转起来。希望这有助于未来的人们;这是将持久性消息传递快速添加到小型应用程序的好方法。

    注意:这不是连接课程的好方法。您可能从config传入JMSTemplate,因此您可以使用一个类定义并将其连接到不同队列的不同模板中。我刚刚这样做是为了提高速度。只需使用你的春天本能:)

答案 1 :(得分:1)

Apache的Active MQ网站提供了一个关于如何在Spring中嵌入代理的示例:http://activemq.apache.org/spring-support.html以及如何定义JMS桥:http://activemq.apache.org/jms-to-jms-bridge.html