springboot integriert die Persistenz von activemq und tpoic sowie das virtuelle Thema (virtuelles Thema)

mq ist in Warteschlangen unterteilt (Warteschlangenmodus, der Produzent erstellt eine Nachricht, die nur von einem Verbraucher verwendet werden kann) (Veröffentlichungs- / Abonnementmodus, der Produzent erstellt eine Nachricht, die von mehreren Verbrauchern verwendet werden kann).

Konfiguration von application.properties

# http port
server.port=9090

env.host.mq=192.168.46.128
#========================================================MQ=================================================#
spring.activemq.broker-url=tcp://${env.host.mq}:61616
spring.activemq.user=admin
spring.activemq.password=admin

spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50


#MQ白名单信任
spring.activemq.packages.trust-all=true

mq Konfigurationsklasse

package com.wl.dubbo.blog.mq;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;

import javax.jms.ConnectionFactory;
import javax.jms.Queue;

/**
 * Created by wl on 2017/12/28.
 */
@Configuration
@EnableJms
public class MqConfig {

    @Value("${spring.activemq.broker-url}")
    private String broker_url;

    @Value("${spring.activemq.user}")
    private String jmsUser;

    @Value("${spring.activemq.password}")
    private String jsmPass;

    private static final String QUEUE_NAME_ = "queue";

    private static final String TOPIC_NAME = "orders";


    @Bean("queue")
    public Queue queueQueue(){
        return new ActiveMQQueue(QUEUE_NAME_);
    }

    @Bean("topicQueue")
    public ActiveMQTopic topicQueue(){
        return new ActiveMQTopic(TOPIC_NAME);
    }

  


    @Bean(name = "activeMQConnectionFactory")
    public ActiveMQConnectionFactory activeMQConnectionFactory(){
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(jmsUser,jsmPass,broker_url);
        activeMQConnectionFactory.setTrustAllPackages(true);

        return activeMQConnectionFactory;
    }



    @Bean(name = "queueListenerFactory")
    public JmsListenerContainerFactory<?> queueListenerFactory(ConnectionFactory activeMQConnectionFactory){
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setPubSubDomain(false);
        factory.setConnectionFactory(activeMQConnectionFactory);
        return factory;
    }

    @Bean(name = "topicListenerFactory")
    public JmsListenerContainerFactory<DefaultMessageListenerContainer> topicListenerFactory(ConnectionFactory activeMQConnectionFactory){
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setPubSubDomain(true);
        factory.setConnectionFactory(activeMQConnectionFactory);
        return factory;

    }


    @Bean
    public JmsMessagingTemplate jmsMessagingTemplate(ConnectionFactory activeMQConnectionFactory){
        return new JmsMessagingTemplate(activeMQConnectionFactory);
    }


}

veröffentlichen 

package com.wl.dubbo.blog.mq;

import org.apache.activemq.command.ActiveMQTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Component;

import javax.jms.Queue;

/**
 * Created by wl on 2017/12/28.
 */
@Component
public class ActiveMQSendService {
    private static final Logger logger = LoggerFactory.getLogger(ActiveMQSendService.class);
    
    private JmsMessagingTemplate jmsMessagingTemplate;

    private Queue queueQueue;

    private ActiveMQTopic activeMQTopic;

    @Autowired
    public ActiveMQSendService(JmsMessagingTemplate jmsMessagingTemplate,
                               Queue queueQueue,
                               ActiveMQTopic topicQueue){

        this.jmsMessagingTemplate = jmsMessagingTemplate;
        this.queueQueue = queueQueue;
        this.activeMQTopic = topicQueue;
    }

    public void sendQueueMessage(String message){
        logger.info("send queue:{}",message);
        jmsMessagingTemplate.convertAndSend(queueQueue,message);
    }

    public void sendTopicMessage(String message){
        logger.info("send topic:{}",message);
        jmsMessagingTemplate.convertAndSend(activeMQTopic,message);
    }

}

Verbraucher

package com.wl.dubbo.blog.mq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import javax.jms.JMSException;

/**
 * Created by wl on 2017/12/28.
 */
@Component
public class ReceiverService {

    private static final Logger logger = LoggerFactory.getLogger(ReceiverService.class);

    @JmsListener(destination = "queue",containerFactory = "queueListenerFactory")
    public void receiveTestQueue(String receiveStr) throws JMSException {
        logger.info("=======================queue:{}",receiveStr);

    }


    @JmsListener(destination = "orders",containerFactory = "topicListenerFactory" )
    public void receiveTopicQueue(String receiveStr) throws JMSException {
        logger.info("=======================orders:{}",receiveStr);

    }

  


}

Starten Sie den Unterricht

package com.wl.dubbo.blog;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;

/**
 * Created by wl on 2018/8/3.
 */
@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,              //不使用数据库
},scanBasePackages = "com.wl")
public class Application {
    private static final Logger logger = LoggerFactory.getLogger(BlogApplication.class);
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(BlogApplication.class);
        app.setWebEnvironment(true);
        app.run(args);
        logger.info("application init success");
    }
}

Testklasse

package com.wl.dubbo.blog;

import com.wl.dubbo.blog.mq.ActiveMQSendService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Created by wl on 2018/8/27.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class ApplicationTest {

    @Autowired
    private ActiveMQSendService activeMQSendService;

    @Test
    public void testSendQueue(){
        activeMQSendService.sendQueueMessage("queue===============");
    }

    @Test
    public void testSendTopic(){
        activeMQSendService.sendTopicMessage("topic================");
    }

}

Die obige Themennachricht ist nicht dauerhaft. Wenn die Themennachricht vor dem Start der konsumierenden Anwendung gesendet wird, kann der Konsument die Nachricht nicht konsumieren. Wenn bei einer verteilten Bereitstellung auf mehreren Computern ein Thema identisch ist, wird die Anwendung häufig verwendet . Die Lösung der oben genannten Probleme erfordert dauerhafte Themen und die Verwendung virtueller Themen

Themenpersistenz

Ändern Sie das Broker-Tag activemq.xml im Verzeichnis activemq_home / config, um das Attribut persistent = "true" hinzuzufügen

 <!--
        The <broker> element is used to configure the ActiveMQ broker.
    -->
    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" persistent="true"  dataDirectory="${activemq.data}">

 Activemq verwendet standardmäßig kahaDB für persistente Daten und wird im Verzeichnis acivemq_home / data / kahaDB gespeichert

Die mq config-Klasse ändert die JmsListenerContainerFactory des Themas

@Bean(name = "topicListenerFactory")
    public JmsListenerContainerFactory<DefaultMessageListenerContainer> topicListenerFactory(ConnectionFactory activeMQConnectionFactory){
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setPubSubDomain(true);//"true" for the Publish/Subscribe domain
        factory.setSubscriptionDurable(true);// Set this to "true" to register a durable subscription,

        factory.setClientId("A");

//
        factory.setConnectionFactory(activeMQConnectionFactory);
        return factory;

    }

Die listenerContainerFactory des persistenten Themas muss setSubscriptionDurable (true) setPubSubDomain (true) und die clientId festlegen

Hinweis: Die für verschiedene Ziele erforderliche clientId der listenerContainerFactory muss unterschiedlich sein. Benennen Sie die clientId daher am besten nach dem Geschäftstyp. Dasselbe Ziel in einer verteilten Bereitstellung: Wenn die Client-ID identisch ist, kann die später gestartete Anwendung das Ziel nicht verwenden (wenn die zuvor gestartete Anwendung geschlossen wurde, kann die später gestartete Anwendung das Ziel verwenden). Wenn Sie einen neuen Zielkonsumenten hinzufügen möchten, müssen Sie daher eine neue listenerContainerFactory erstellen, und die clientId ist anders

Virtuelles Thema (Virtuelles Thema)

Das virtuelle Thema wird über die Warteschlange realisiert. Bei der verteilten Bereitstellung wird dasselbe Ziel nicht wiederholt verwendet

Der Name des virtuellen Themas muss mit dem Präfix VirtualTopic. Beginnen (kann geändert werden, indem die Konfiguration von activemq.xml unter activemq_home / conf geändert wird).

Das Ziel des virtuellen Themas muss mit dem Präfix Consumer. *. VirtualTopic. Beginnen (es kann durch Ändern der Konfiguration activemq.xml unter activemq_home / conf geändert werden). * Die Nummer entspricht der Gruppierung

Beispiel: Wenn der Warteschlangenname VirtualTopic.Orders lautet, lautet das Ziel Consumer.A.VirtualTopic.Orders, Consumer.B.VirtualTopic.Orders in einer verteilten Bereitstellung. Consumer.A.VirtualTopic.Orders wird nur einmal verwendet, wenn Consumer.B. VirtualTopic. Bestellungen werden nur einmal verbraucht

mq config wird wie folgt hinzugefügt

private static final String VIRTUAL_TOPIC_NAME = "VirtualTopic.Orders";


    @Bean("virtualTopicQueue")
    public ActiveMQTopic virtualTopicQueue(){
        return new ActiveMQTopic(VIRTUAL_TOPIC_NAME);
    }

veröffentlichen geändert wie folgt

package com.wl.dubbo.blog.mq;

import org.apache.activemq.command.ActiveMQTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Component;

import javax.jms.Queue;

/**
 * Created by wl on 2017/12/28.
 */
@Component
public class ActiveMQSendService {
    private static final Logger logger = LoggerFactory.getLogger(ActiveMQSendService.class);

    private JmsMessagingTemplate jmsMessagingTemplate;

    private Queue queueQueue;

    private ActiveMQTopic topicQueue;

    private ActiveMQTopic virtualTopicQueue;

    @Autowired
    public ActiveMQSendService(JmsMessagingTemplate jmsMessagingTemplate,
                               Queue queueQueue,
                               ActiveMQTopic topicQueue,
                               ActiveMQTopic virtualTopicQueue){

        this.jmsMessagingTemplate = jmsMessagingTemplate;
        this.queueQueue = queueQueue;
        this.topicQueue = topicQueue;
        this.virtualTopicQueue = virtualTopicQueue;
    }

    public void sendQueueMessage(String message){
        logger.info("send queue:{}",message);
        jmsMessagingTemplate.convertAndSend(queueQueue,message);
    }

    public void sendTopicMessage(String message){
        logger.info("send topic:{}",message);
        jmsMessagingTemplate.convertAndSend(topicQueue,message);
    }

    public void sendVirtualTopicQueue(String message){
        logger.info("send virtualTopic:{}",message);
        jmsMessagingTemplate.convertAndSend(virtualTopicQueue,message);
    }


}

Consumer fügt den Listener VirtualTopic.Orders hinzu

@JmsListener(destination = "Consumer.B.VirtualTopic.Orders",containerFactory = "queueListenerFactory" )
    public void receiveTopicVirtualQueue(String receiveStr) throws JMSException {
        logger.info("=======================Consumer.B.VirtualTopic.topic:{}",receiveStr);

    }

Beachten Sie, dass die verwendete containerFactory queueListenerFactory ist (im Gegensatz zum Thema können verschiedene Warteschlangen dieselbe containerFactory verwenden).

Prüfung

@Test
    public void testSendVirtualTopic(){
        activeMQSendService.sendVirtualTopicQueue("virtualTopic==============");
    }

Ergebnis

2018-08-28 00:18:18,814 INFO (DefaultLifecycleProcessor.java:343)- Starting beans in phase 2147483647
2018-08-28 00:18:19,228 INFO (StartupInfoLogger.java:57)- Started ApplicationTest in 6.17 seconds (JVM running for 7.442)
2018-08-28 00:18:19,291 INFO (ActiveMQSendService.java:50)- send virtualTopic:virtualTopic==============
2018-08-28 00:18:22,280 INFO (ReceiverService.java:31)- =======================Consumer.B.VirtualTopic.topic:virtualTopic==============

 

Ich denke du magst

Origin blog.csdn.net/name_is_wl/article/details/82120329
Empfohlen
Rangfolge