SpringBoot整合ActiveMQ

一、ActiveMQ介绍

1. ActiveMQ持久化机制
  • ActiveMQ作为一个消息中间件,提供了持久化机制功能,并且是实时持久化的。
  • 当持久化机制开启后,ActiveMQ中间件服务器宕机时,保证队列中的消息不会被丢失。
  • SpringBoot整合ActiveMQ默认开启了持久化机制。
2. ActiveMQ可靠消息机制
  • JMS默认是自动签收消息的,消费者获取到消息后,无论消费者对该消息处理业务逻辑是否成功,都会默认为已经消费的。

那么如何保证消息被消费成功呢?

  • 使用手动签收模式:
    消息中间件将消息推送给消费者,消费者接收到消息后,必须受手动发送命令告诉消息中间件消费成功,否则消息中间件将重新推送这条消息。
  • 以事务形式发送或者接收:
    生产者发送消息需要提交事务,消费者消费成功消息后也需要提交事务,这样就自动签收表示消费成功,消息中间件会删除这条消息。如果消费者没有提交事务,则消息中间件不会删除消息,而是当消息中间件有新的消息后,连同上次为成功消费的消息一起推送,消费者获取到消息进行重新消费。
3. ActiveMQ遵循JMS规范

JMS通讯模式:

  • 发布/订阅模式(sub/pub 一对多 topic): 如果消费者集群的话,每个消费者都会进行消费。
  • 消息队列(p2p 一对一 queue):如果消费者集群的话,每个消费者均摊进行消费(轮询)。

二、SpringBoot整合ActiveMQ(点对点模式)

希望每条消息都被一个消费者成功消费使用点对点模式,并且使用自动签收或者事务提交。

生产者:
  • 引入Maven依赖
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>activemq-queue-producer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>activemq-queue-producer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- activemq依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 引入 application.yml配置
spring:
  activemq:
    broker-url: tcp://127.0.0.1:61616    # ActiveMQ消息中间件服务器通讯地址
    user: admin  # 用户名
    password: admin  #密码
queue: springboot-queue   #自定义队列名,等下程序中会用到
server:
  port: 8080

  • 创建QueueConfig
@Configuration
public class QueueConfig {
	//获取队列名
	@Value("${queue}")
	private String queue;

	//注册bean
	@Bean
	public Queue logQueue() {
		return new ActiveMQQueue(queue);
	}
}

  • 创建Producer
@Component
@EnableScheduling
public class Producer {
	@Autowired
	private JmsMessagingTemplate jmsMessagingTemplate;
	@Autowired
	private Queue queue;
	
	//每隔5秒向消息队列发送消息
	@Scheduled(fixedDelay = 5000)
	public void send() {
		 jmsMessagingTemplate.convertAndSend(queue,"基于点对点发送消息: "+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
	}
}

  • 启动类
@SpringBootApplication
@EnableScheduling  //开启任务调度
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}

消费者:
  • 引入 maven依赖
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>activemq-queue-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>activemq-queue-consumer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- activemq依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 引入 YML配置
spring:
  activemq:
    broker-url: tcp://127.0.0.1:61616    # ActiveMQ消息中间件服务器通讯地址
    user: admin    #用户名
    password: admin    #密码
queue: springboot-queue     #自定义队列名,等下程序中会用到
server:
  port: 8081

  • 创建Consumer

@Component
public class Consumer {
    @Value("${server.port}")
    private String port;

    @JmsListener(destination = "${queue}")     //监听的队列,配置文件中的queue属性
    public void receive(String msg){
        System.out.println("点对点模式消费者"+port+"收到msg:  " + msg);
    }
}


  • 启动类
@SpringBootApplication
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}


  • 测试
    我们进入ActiveMQ管理页面可以看到一些数据:
    在这里插入图片描述
    两个消费者分摊消费(默认轮询,一条消息只被消费一次):
    在这里插入图片描述
    在这里插入图片描述

三、SpringBoot整合ActiveMQ(发布与订阅模式)

希望条消息被多个消费者或不被任何消费者消费,采用发布订阅模式。

发布与订阅模式其实与点对点使用方式基本一样,需要改的地方如下:
Producer修改:

  • 修改yml配置:删除以前的自定义队列名,新增自定义主题名:topic: spring-topic
  • 配置类注册类型为Topic,即使用到Queue的地方都改成Topic

Consumer修改:

  • 注意:SpringBoot整合ActiveMQ默认值开启了点对点模式,没有开启发布/订阅模式,需要配置如下:

    开启发布订阅
    jms: 
       pub-sub-domain: true
    
详细教程:
生产者:
  • 引入Maven依赖
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>activemq-topic-producer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>activemq-topic-producer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- activemq依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 引入 application.yml配置
spring:
  activemq:
    broker-url: tcp://127.0.0.1:61616    # ActiveMQ消息中间件服务器通讯地址
    user: admin  # 用户名
    password: admin  #密码
topic: springboot-topic   #自定义主题名,等下程序中会用到
server:
  port: 8080

  • 创建TopicConfig
@Configuration
public class TopicConfig {
    //获取主题名
    @Value("${topic}")
    private String topic;

    //注册bean
    @Bean
    public Topic logQueue() {
        return new ActiveMQTopic(topic);
    }
}
  • 创建Producer
@Component
@EnableScheduling
public class Producer {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;
    @Autowired
    private Topic topic;

    //每隔5秒向消息队列发送消息
    @Scheduled(fixedDelay = 5000)
    public void send(){
        jmsMessagingTemplate.convertAndSend(topic,"基于发布/订阅发送消息: "+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}
  • 启动类
@EnableScheduling
@SpringBootApplication
public class ActivemqTopicApplication {

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

}

生产者:
  • 引入Maven依赖
 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>activemq-topic-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>activemq-topic-consumer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- activemq依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 引入 application.yml配置( 注意开启发布/订阅,否者消费者无法获取到消息)
spring:
  activemq:
    broker-url: tcp://127.0.0.1:61616    # ActiveMQ消息中间件服务器通讯地址
    user: admin  # 用户名
    password: admin  #密码
  # 开启发布订阅(注意:SpringBoot整合ActiveMQ默认没有开启发布/订阅模式,因此需要手动配置   点对点模式是自动开启的)
  jms:
    pub-sub-domain: true

topic: springboot-topic   #自定义主题名,等下程序中会用到
server:
  port: 8082
  • 创建Consumer
@Component
public class Consumer {
    @Value("${server.port}")
    private String port;

    @JmsListener(destination = "${topic}")     //监听的队列,配置文件中的queue属性
    public void receive(String msg){
        System.out.println("发布/订阅模式消费者"+port+"收到msg:  " + msg);
    }
}
  • 启动类
@SpringBootApplication
public class ActivemqTopicConsumerApplication {

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

}
测试

先启动两个消费者订阅消息(订阅前的消息是无法被消费的),端口分别为8081,8082; 然后再启动生产者。
ActiveMQ管理页面可以看到一些数据:
可以看到出队数量大于入队数量,这是说明两个消费者都消费了消息,只要订阅了该主题的消费者都会消费消息。
在这里插入图片描述

两个消费者都进行了消费(说明只要订阅了该主题的消费者都会对消息进行消费,一条消息被消费多次):
在这里插入图片描述
在这里插入图片描述

--------------------------------- 学习不易,需要坚持 ---------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值