【ActiveMQ】使用学习

【ActiveMQ】使用学习

转载:

1、启动

activemq start

2、停止

activemq stop

 

http://localhost:8161

admin / admin

 

Queue - Point-to-Point (点对点)

一条消息只能被一个消费者消费, 且是持久化消息 - 当没有可用的消费者时,该消息保存直到被消费为止;当消息被消费者收到但不响应时(具体等待响应时间是多久,如何设置,暂时还没去了解),该消息会一直保留或会转到另一个消费者当有多个消费者的情况下。当一个Queue有多可用消费者时,可以在这些消费者中起到负载均衡的作用。

Topic - Publisher/Subscriber Model (发布/订阅者)

一条消息发布时,所有的订阅者都会收到,topic有2种模式,Nondurable subscription(非持久订阅)和durable subscription (持久化订阅 - 每个持久订阅者,都相当于一个持久化的queue的客户端), 默认是非持久订阅。

持久化:消息产生后,会保存到文件/DB中,直到消息被消费, 如上述Queue的持久化消息。默认保存在ActiveMQ中:%ActiveMQ_Home%/data/kahadb

非持久化:消息不会保存,若当下没有可用的消费者时,消息丢失。

Spring Boot 中使用

配置 JmsTemplate 和 DefaultJmsListenerContainerFactory

package ycx.activemq.config;

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.core.JmsTemplate;

import javax.jms.ConnectionFactory;

@Configuration
@EnableJms
public class ActiveMQConfig {
    public static final String MY_QUEUE = "ycx.queue";
    public static final String MY_TOPIC = "ycx.topic";

    @Bean("queueJmsTemplate")
    public JmsTemplate queueJmsTemplate(ConnectionFactory connectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
        jmsTemplate.setDefaultDestinationName(MY_QUEUE);
        return jmsTemplate;
    }

    @Bean("queueContainerFactory")
    public DefaultJmsListenerContainerFactory queueContainerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setSessionTransacted(true);
        factory.setConcurrency("1");
        factory.setRecoveryInterval(1000L);
        return factory;
    }

    @Bean("topicJmsTemplate")
    public JmsTemplate topicJmsTemplate(ConnectionFactory connectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
        jmsTemplate.setDefaultDestinationName(MY_QUEUE);
        jmsTemplate.setPubSubDomain(true);
        return jmsTemplate;
    }

    @Bean("topicContainerFactory")
    public DefaultJmsListenerContainerFactory topicContainerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setSessionTransacted(true);
        factory.setConcurrency("1");
        factory.setRecoveryInterval(1000L);
        factory.setPubSubDomain(true);
        return factory;
    }
}

 

连接工厂使用自动注入进来的,如果不想使用默认的可以自动配置

spring:
  activemq:
    broker-url: tcp://localhost:61616
    user: admin
    password: admin

或者在 java中指定

@Bean
public ConnectionFactory connectionFactory() {
    return new ActiveMQConnectionFactory(MY_USERNAME, MY_PASSWORD, MY_BROKER_URL);
}

 

定义监听器

Queue监听器A

package ycx.activemq.listener;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import ycx.activemq.config.ActiveMQConfig;

@Component
public class QueueMessageListenerA {

    @JmsListener(destination = ActiveMQConfig.MY_QUEUE, containerFactory = "queueContainerFactory")
    public void handleMessage(String msg) {
        System.out.println("queue A >>> " + msg);
    }
}

Queue监听器B

package ycx.activemq.listener;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import ycx.activemq.config.ActiveMQConfig;

@Component
public class QueueMessageListenerB {

    @JmsListener(destination = ActiveMQConfig.MY_QUEUE, containerFactory = "queueContainerFactory")
    public void handleMessage(String msg) {
        System.out.println("queue B >>> " + msg);
    }
}

Topic监听器A

package ycx.activemq.listener;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import ycx.activemq.config.ActiveMQConfig;

@Component
public class TopicMessageListenerA {
    @JmsListener(destination = ActiveMQConfig.MY_TOPIC, containerFactory = "topicContainerFactory")
    public void handleMessage(String msg) { System.out.println("topic A >>> " + msg); }
}

Topic监听器B

package ycx.activemq.listener;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import ycx.activemq.config.ActiveMQConfig;

@Component
public class TopicMessageListenerB {
    @JmsListener(destination = ActiveMQConfig.MY_TOPIC, containerFactory = "topicContainerFactory")
    public void handleMessage(String msg) {
        System.out.println("topic B >>> " + msg);
    }
}

Topic监听器C

package ycx.activemq.listener;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import ycx.activemq.config.ActiveMQConfig;

@Component
public class TopicMessageListenerC {
    @JmsListener(destination = ActiveMQConfig.MY_TOPIC, containerFactory = "topicContainerFactory")
    public void handleMessage(String msg) {
        System.out.println("topic C >>> " + msg);
    }
}

 

测试

package ycx.activemq;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ycx.activemq.config.ActiveMQConfig;

import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
@RestController
public class ActivemqServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ActivemqServerApplication.class, args);
    }

    @Autowired
    @Qualifier("queueJmsTemplate")
    JmsTemplate queueJmsTemplate;

    @Autowired
    @Qualifier("topicJmsTemplate")
    JmsTemplate topicJmsTemplate;

    @RequestMapping("/queue")
    public Object queue() {
        String content = "queue send: " + LocalTime.now().toString();
        queueJmsTemplate.convertAndSend(ActiveMQConfig.MY_QUEUE, content);

        Map<String, String> res = new HashMap<>();
        res.put("content", content);
        return res;
    }

    @RequestMapping("/topic")
    public Object topic() {
        String content = "topic send : " + LocalTime.now().toString();
        topicJmsTemplate.convertAndSend(ActiveMQConfig.MY_TOPIC, content);

        Map<String, String> res = new HashMap<>();
        res.put("content", content);
        return res;
    }
}

访问地址: http://localhost:8080/topic

订阅 收到消息,所有的监听器都受到消息

topic B >>> topic send : 12:22:05.024
topic C >>> topic send : 12:22:05.024
topic A >>> topic send : 12:22:05.024

访问地址:http://localhost:8080/queue

队列 收到消息,只有一个监听器收到消息

queue B >>> queue send: 12:22:58.491

 

posted @ 2019-05-01 19:33  翠微  阅读(322)  评论(0编辑  收藏  举报