programing

스프링 부트 여러 ActiveMQ 인스턴스 구성

sourcejob 2023. 7. 28. 21:58
반응형

스프링 부트 여러 ActiveMQ 인스턴스 구성

한 ActiveMQ 인스턴스의 큐에서 다른 ActiveMQ 인스턴스로 메시지를 이동해야 합니다.스프링 부트 구성을 사용하여 두 개의 서로 다른 ActiveMQ 인스턴스에 연결하는 방법이 있습니까?

연결 팩토리를 여러 개 만들어야 합니까?그렇다면 JmsTemplate는 연결할 ActiveMQ 인스턴스를 어떻게 알 수 있습니까?

  @Bean
    public ConnectionFactory connectionFactory() {
        return new ActiveMQConnectionFactory(JMS_BROKER_URL);
    }

도움말 및 코드 예제가 유용합니다.

잘 부탁드립니다. GM님.

@Chris의 응답 외에도 다른 스포츠를 사용하여 다른 BrokerService 인스턴스를 생성하고 각 브로커에 연결하기 위해 다른 ConnectionFactory를 생성해야 하며 이러한 서로 다른 팩토리를 사용하여 서로 다른 JmsTemplate를 생성하여 서로 다른 브로커에게 메시지를 보내야 합니다.

예:

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

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;

@Configuration
public class ActiveMQConfigurationForJmsCamelRouteConsumeAndForward {
    public static final String LOCAL_Q = "localQ";
    public static final String REMOTE_Q = "remoteQ";

    @Bean
    public BrokerService broker() throws Exception {
        final BrokerService broker = new BrokerService();
        broker.addConnector("tcp://localhost:5671");
        broker.setBrokerName("broker");
        broker.setUseJmx(false);
        return broker;
    }

    @Bean
    public BrokerService broker2() throws Exception {
        final BrokerService broker = new BrokerService();
        broker.addConnector("tcp://localhost:5672");
        broker.setBrokerName("broker2");
        broker.setUseJmx(false);
        return broker;
    }

    @Bean
    @Primary
    public ConnectionFactory jmsConnectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:5671");
        return connectionFactory;
    }

    @Bean
    public QueueConnectionFactory jmsConnectionFactory2() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:5672");
        return connectionFactory;
    }

    @Bean
    @Primary
    public JmsTemplate jmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory(jmsConnectionFactory());
        jmsTemplate.setDefaultDestinationName(LOCAL_Q);
        return jmsTemplate;
    }

    @Bean
    public JmsTemplate jmsTemplate2() {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory(jmsConnectionFactory2());
        jmsTemplate.setDefaultDestinationName(REMOTE_Q);
        return jmsTemplate;
    }

    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
            DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerFactory2(
            @Qualifier("jmsConnectionFactory2") ConnectionFactory connectionFactory,
            DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }
}

메시지를 한 AMQ 인스턴스에서 사용할 수 있는 다른 인스턴스로 이동하려면JmsBridgeConnectors:

아래 예제에서는 Camel 또는 JmsBridgeConnectors가 메시지를 사용하여 전달하기 때문에 메시지를 전달할 대기열에 여러 소비자를 둘 수 없습니다.메시지의 복사본만 전달하려면 몇 가지 해결책이 있습니다. 1 - 대기열을 주제로 변환하고, 지속적인 구독 또는 소급 소비자를 통해 오프라인 소비자의 메시지를 관리합니다. 2 - 대기열을 복합 대기열로 변환하고 대상을 사용합니다.메시지를 다른 대기열로 복사하기 위한 가로채기. 3 - 브로커의 네트워크에 NetworkConnector 사용

@Bean
public BrokerService broker() throws Exception {
    final BrokerService broker = new BrokerService();
    broker.addConnector("tcp://localhost:5671");
    SimpleJmsQueueConnector simpleJmsQueueConnector = new SimpleJmsQueueConnector();
    OutboundQueueBridge bridge = new OutboundQueueBridge();
    bridge.setLocalQueueName(LOCAL_Q);
    bridge.setOutboundQueueName(REMOTE_Q);
    OutboundQueueBridge[] outboundQueueBridges = new OutboundQueueBridge[] { bridge };
    simpleJmsQueueConnector.getReconnectionPolicy().setMaxSendRetries(ReconnectionPolicy.INFINITE);
    simpleJmsQueueConnector.setOutboundQueueBridges(outboundQueueBridges);
    simpleJmsQueueConnector.setLocalQueueConnectionFactory((QueueConnectionFactory) jmsConnectionFactory());
    simpleJmsQueueConnector.setOutboundQueueConnectionFactory(jmsConnectionFactory2());
    JmsConnector[] jmsConnectors = new JmsConnector[] { simpleJmsQueueConnector };
    broker.setJmsBridgeConnectors(jmsConnectors);
    broker.setBrokerName("broker");
    broker.setUseJmx(false);
    return broker;
}

또는 아래와 같은 Camel을 사용합니다.

@Bean
public CamelContext camelContext() throws Exception {
    CamelContext context = new DefaultCamelContext();
    context.addComponent("inboundQueue", ActiveMQComponent.activeMQComponent("tcp://localhost:5671"));
    context.addComponent("outboundQueue", ActiveMQComponent.activeMQComponent("tcp://localhost:5672"));
    context.addRoutes(new RouteBuilder() {
        public void configure() {
            from("inboundQueue:queue:" + LOCAL_Q).to("outboundQueue:queue:" + REMOTE_Q);
        }
    });
    context.start();
    return context;
}

다른 JmsTemplates를 사용하려면 Producer가 다음과 같아야 합니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class Producer implements CommandLineRunner {

    @Autowired
    private JmsTemplate jmsTemplate;

    @Autowired
    @Qualifier("jmsTemplate2")
    private JmsTemplate jmsTemplate2;

    @Override
    public void run(String... args) throws Exception {
        send("Sample message");
    }

    public void send(String msg) {
        this.jmsTemplate.convertAndSend(ActiveMQConfigurationForJmsCamelRouteConsumeAndForward.LOCAL_Q, msg);
        this.jmsTemplate2.convertAndSend(ActiveMQConfigurationForJmsCamelRouteConsumeAndForward.REMOTE_Q, msg);
    }
}

및 소비자:

import javax.jms.Session;

import org.apache.activemq.ActiveMQSession;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class Consumer {

    @JmsListener(destination = ActiveMQConfigurationForJmsCamelRouteConsumeAndForward.REMOTE_Q, containerFactory = "jmsListenerContainerFactory2")
    public void receiveQueue(Session session, String text) {
        System.out.println(((ActiveMQSession) session).getConnection().getBrokerInfo());
        System.out.println(text);
    }
}

여러 개의 인스턴스를 생성해야 합니다.JmsTemplate로서의 예.Beans응용 프로그램에서 다음과 같은 조합을 사용합니다.@Qualifier그리고.@Primary다음을 나타내는 주석JmsTemplate인스턴스는 어디로 가야 합니다.

예를들면

@Bean("queue1")
@Primary
public JmsTemplate getQueue1(@Qualifier("connectionFactory1")ConnectionFactory factory...){
...
}

@Bean("queue2")
@Primary
public JmsTemplate getQueue2(@Qualifier("connectionFactory2")ConnectionFactory factory...){
...
}

...

@Autowired
@Qualifier("queue1")
private JmsTemplate queue1;
...

자세한 내용은 여기를 참조하십시오.

대기열 소비 장치에 스프링 부트 기본값을 사용할 수 있습니다.

@JmsListener(destination = “queue.name")
public void consumer(String message) {
    // consume the message
}

그리고 프로듀서를 위해 다른 JmsTemplate @Bean을 생성할 수 있습니다.

@Bean
public JmsTemplate jmsTemplate() {
    return new JmsTemplate(new ActiveMQConnectionFactory("tcp://localhost:5671"));
}

이렇게 하면 원하는 만큼 동적으로 브로커/청취자를 등록할 수 있습니다.

import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.JmsListenerConfigurer;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerEndpointRegistrar;
import org.springframework.jms.config.SimpleJmsListenerEndpoint;

import javax.jms.Message;
import javax.jms.MessageListener;

@Configuration
public class CustomJmsConfigurer implements JmsListenerConfigurer {

    @Override
    public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
        ActiveMQConnectionFactory amqConnectionFactory = new ActiveMQConnectionFactory();
        amqConnectionFactory.setBrokerURL("brokerUrl");
        amqConnectionFactory.setUserName("user");
        amqConnectionFactory.setPassword("password");
        amqConnectionFactory.setExclusiveConsumer(true);

        DefaultJmsListenerContainerFactory containerFactory = new DefaultJmsListenerContainerFactory();
        containerFactory.setConnectionFactory(amqConnectionFactory);

        SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
        endpoint.setId("someIdentifier");
        endpoint.setDestination("queueName");
        endpoint.setMessageListener(new MessageListener() {

            @Override
            public void onMessage(Message message) {
                // Do your stuff
            }
        });
        registrar.registerEndpoint(endpoint, containerFactory);
    }
}

언급URL : https://stackoverflow.com/questions/43399072/spring-boot-configure-multiple-activemq-instances

반응형