【问题标题】:Embedding ActiveMQ broker in Spring-MVC Tomcat webapp在 Spring-MVC Tomcat webapp 中嵌入 ActiveMQ 代理
【发布时间】:2011-03-31 14:19:22
【问题描述】:

我有一个小型 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 库中需要 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)。

更新 2。我已经正确回答了,下面。不需要任何 amq 的东西!

【问题讨论】:

    标签: spring tomcat spring-mvc jms activemq


    【解决方案1】:

    这是怎么做的。

    假设

    1. 您正在通过 http://destination-box:61616 连接到远程目标
    2. 您将通过 vm://localhost:7001 上的 VM transport 连接到本地代理
    3. 您有两个要桥接到的远程队列:queue1queue2

    前:命名空间

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

    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。创建代理连接工厂

    这个连接到上面的broker:

    <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。创建 JMS 模板以连接到本地 bean

    我只会在这里为 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);
          }
        });
      }
    }
    

    你就完成了!实际上并没有太痛苦,但需要一段时间才能让它发挥作用。希望这对将来的人们有所帮助;这是向小应用快速添加持久消息的好方法。

    注意:这不是连接类的好方法。您可能会从配置中传入一个 JMSTemplate,因此您可以使用一个类定义并将其连接到不同的模板中以用于不同的队列。我刚刚这样做是为了速度。只需使用您的 Spring 直觉:)

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我正在尝试 :) 在 bean 文件顶部添加 xmlns:amq 声明,添加 xbean-spring-3.4.jar 文件,并使用简单的代理声明( ) 我现在得到一个 org.springframework.beans.factory.BeanCreationException,这是因为它显然找不到 org/osgi/framework/BundleException。这就是我问这个问题的全部原因:)
      • 在 Java 编程中寻找 JAR 文件和设置 CLASSPATH 是一件很痛苦的事情。我在 org.osgi.core-4.1.0.jar 中发现了 BundleException,它是 Active MQ 5.3.2 包的一部分。
      猜你喜欢
      • 1970-01-01
      • 2012-06-11
      • 2011-05-28
      • 2012-06-24
      • 2014-10-16
      • 2012-05-13
      • 2013-01-06
      • 2022-01-19
      • 2015-04-04
      相关资源
      最近更新 更多