あるActiveMQインスタンスのキューから別のActiveMQインスタンスにメッセージを移動する必要があります。スプリングブート構成を使用して2つの異なるActiveMQインスタンスに接続する方法はありますか?
複数のconnectionFactoriesを作成する必要がありますか?その場合、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-キューを複合キューに変換し、DestinationsInterceptorsを使用してメッセージを別のキューにコピーします。 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;
}
または、以下のようなキャメルを使用することにより:
@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を使用するには、プロデューサーはこのようにする必要があります:
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;
...
詳細は here を参照してください。
キューコンシューマのSpring Bootデフォルトを使用できます
@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);
}
}