使用JMS和spring为ActiveMQ的生产者客户端重试机制

时间:2017-04-10 15:58:57

标签: jms activemq

对于使用带有JMS的ActiveMQ(更确切地说,使用JmsTemplate)和弹簧框架的生产者,是否存在重试机制/解决方案的机制或示例实现?
我想要处理的用例是,当代理不可用时,例如,我想进行一些重试,最多6次(如果可能的话,每次重复之间都有指数延迟)。因此,我还需要跟踪每次尝试之间的消息重试次数。 我知道消费者的重新发送政策,但我也希望实现可靠的生产者客户端

谢谢, 西麦

2 个答案:

答案 0 :(得分:3)

我认为最简单的方法是通过使用启用了持久性的嵌入式代理来使用存在的内容,生成器必须使用它来发送消息,并通过创建Camel路由从本地队列读取并转发到远程的或使用JmsBridgeConnectorNetworkConnector坚果我认为JmsBridgeConnector更容易。 这是一个Spring代码示例: 制作人必须使用jmsConnectionFactory()来创建ConnectionFactory

package com.example.amq;

import java.io.File;

import javax.jms.ConnectionFactory;
import javax.jms.QueueConnectionFactory;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.network.jms.JmsConnector;
import org.apache.activemq.network.jms.OutboundQueueBridge;
import org.apache.activemq.network.jms.ReconnectionPolicy;
import org.apache.activemq.network.jms.SimpleJmsQueueConnector;
import org.apache.activemq.store.PersistenceAdapter;
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ActiveMQConfiguration {
    public static final String DESTINATION_NAME = "localQ";

    @Bean // (initMethod = "start", destroyMethod = "stop")
    public BrokerService broker() throws Exception {
        final BrokerService broker = new BrokerService();
        broker.addConnector("vm://localhost");
        SimpleJmsQueueConnector simpleJmsQueueConnector = new SimpleJmsQueueConnector();
        OutboundQueueBridge bridge = new OutboundQueueBridge();
        bridge.setLocalQueueName(DESTINATION_NAME);
        bridge.setOutboundQueueName("remoteQ");
        OutboundQueueBridge[] outboundQueueBridges = new OutboundQueueBridge[] { bridge };
        simpleJmsQueueConnector.getReconnectionPolicy().setMaxSendRetries(ReconnectionPolicy.INFINITE);
        simpleJmsQueueConnector.setOutboundQueueBridges(outboundQueueBridges);
        simpleJmsQueueConnector.setLocalQueueConnectionFactory((QueueConnectionFactory) jmsConnectionFactory());
        simpleJmsQueueConnector.setOutboundQueueConnectionFactory(outboundQueueConnectionFactory());
        JmsConnector[] jmsConnectors = new JmsConnector[] { simpleJmsQueueConnector };
        broker.setJmsBridgeConnectors(jmsConnectors);
        PersistenceAdapter persistenceAdapter = new KahaDBPersistenceAdapter();
        File dir = new File(System.getProperty("user.home") + File.separator + "kaha");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        persistenceAdapter.setDirectory(dir);
        broker.setPersistenceAdapter(persistenceAdapter);
        broker.setPersistent(true);
        broker.setUseShutdownHook(false);
        broker.setUseJmx(true);
        return broker;
    }

    @Bean
    public QueueConnectionFactory outboundQueueConnectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                "auto://localhost:5671");
        connectionFactory.setUserName("admin");
        connectionFactory.setPassword("admin");
        return connectionFactory;
    }

    @Bean
    public ConnectionFactory jmsConnectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost");
        connectionFactory.setObjectMessageSerializationDefered(true);
        connectionFactory.setCopyMessageOnSend(false);
        return connectionFactory;
    }
}

使用Camel:

import org.apache.activemq.camel.component.ActiveMQComponent;
import org.apache.activemq.camel.component.ActiveMQConfiguration;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;

public class ActiveMQCamelBridge {

    public static void main(String args[]) throws Exception {
        CamelContext context = new DefaultCamelContext();
        context.addComponent("inboundQueue", ActiveMQComponent.activeMQComponent("tcp://localhost:61616"));
        ActiveMQComponent answer = ActiveMQComponent.activeMQComponent("tcp://localhost:5671");
        if (answer.getConfiguration() instanceof ActiveMQConfiguration) {
            ((ActiveMQConfiguration) answer.getConfiguration()).setUserName("admin");
            ((ActiveMQConfiguration) answer.getConfiguration()).setPassword("admin");
        }
        context.addComponent("outboundQueue", answer);
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("inboundQueue:queue:localQ").to("outboundQueue:queue:remoteQ");
            }
        });
        context.start();
        Thread.sleep(60 * 5 * 1000);
        context.stop();
    }
}

答案 1 :(得分:0)

生产者不提供像消费者那样的任何重试机制。您需要在代码中确保生产者发送的消息由代理确认。