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

Rob*_*ant 6 spring tomcat activemq-classic jms spring-mvc

我有一个小型的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>
Run Code Online (Sandbox Code Playgroud)

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

谢谢

更新.一些修复:

  1. Eclipse没有正确找到amq命名空间.是你找出为什么这是破碎的,这是一个容易解决.
  2. 正如Miklos在下面的评论中所说,你需要在webapp lib中使用org.osgi.core-4.1.0.jar.从ActiveMQ lib/optional文件夹中获取此信息.
  3. 您还需要Apache Commons xbean-spring-3.4.jar.得到它在这里.
  4. 指南让我了解了接下来的几个障碍.这是完美的,除了在几个地方属性名称不正确(brokername应该是brokerName,而physicalname应该是physicalName).

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

Rob*_*ant 8

这是怎么做的.

假设

  1. 您正在http:// destination-box:61616上连接到远程目标
  2. 您将通过VM传输连接到本地代理,位于vm:// localhost:7001
  3. 你有两个远程队列要缩小到:队列1队列2

Pre:命名空间

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

xmlns:p="http://www.springframework.org/schema/p"
xmlns:jms="http://www.springframework.org/schema/jms"
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

2.创建代理连接工厂

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

<bean id="brokerConnectionFactory"
 class="org.apache.activemq.ActiveMQConnectionFactory"
 p:brokerURL="vm://localhost:7001" />
Run Code Online (Sandbox Code Playgroud)

然后用CachingConnectionFactory包装它(几乎总是一个好主意):

<bean id="cachingBrokerConnectionFactory"
 class="org.springframework.jms.connection.CachingConnectionFactory"
 p:targetConnectionFactory-ref="brokerConnectionFactory"
 p:sessionCacheSize="10" />
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

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

<bean id="queue1JMSTemplate"
 class="org.springframework.jms.core.JmsTemplate"
 p:connectionFactory-ref="cachingBrokerConnectionFactory"
 p:defaultDestination-ref="queue1destination" />
Run Code Online (Sandbox Code Playgroud)

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);
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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