本例为本地操作消息队列,故需要本地安装ActiveMQ。
1、本地安装ActiveMQ。
(1)、下载地址:ActiveMQ
(2)、解压后,根据电脑操作系统是32位或者64位选择对应的activemq.bat文件,启动ActiveMQ。
启动成功,则显示如下内容
(3)、成功之后在浏览器输入http://127.0.0.1:8161/地址,可以看到ActiveMQ的管理页面,用户名和密码默认都是admin
2、搭建一个springboot项目,可参照之前的博客进行搭建
(1)、添加pom依赖如下(本例调用junit测试,如果不用junit测试,可忽略junit的依赖)
<!-- ActiveMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!-- Junit -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
(2)、在application.yml中添加如下的配置(注意在yml配置文件中不可以使用tab缩进,必需使用空格键)
broker-url:设置 failover:(tcp://127.0.0.1:61616),则可以避免,消息队列宕机,仅存消费者,之后恢复消息队列。消费者链接消息队列失败的情况
spring:
activemq: #消息队列
broker-url: tcp://localhost:61616
in-memory: true #true 表示使用内置的MQ,false则连接服务器
pool:
enabled: false #true表示使用连接池;false时,每发送一条数据创建一个连接
(3)、创建生产者
import javax.jms.Destination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
@Service
public class Producer {
@Autowired // 也可以注入JmsTemplate,JmsMessagingTemplate对JmsTemplate进行了封装
private JmsMessagingTemplate jmsTemplate;
// 发送消息
public void sendMessage(Destination destination, final String message) {
System.out.println("生产者发布消息: "+message);
// 将消息message放入消息队列destination
jmsTemplate.convertAndSend(destination, message);
}
// 监听消息队列out.queue,打印消息队列out.queue收到的消息内容,这里作为消费者对生产者的反馈
@JmsListener(destination="out.queue")
public void consumerMessage(String text){
System.out.println("生产者收到消费者的回复报文为:"+text);
}
}
(4)、创建消费者1,仅接收生产者的发布信息
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class Consumer {
// 消费者1接仅收生产者的消息
// 使用JmsListener配置消费者监听的队列,其中text是接收到的消息
@JmsListener(destination = "mytest.queue")
public void receiveQueue(String text) {
System.out.println("消费者1收到生产者的报文为:"+text);
}
}
(5)、创建消费者2,接收生产者的发布信息,且对生产者的发布信息进行回复
package com.zw.jms;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;
@Component
public class Consumer2 {
// 消费者2接收生产者的消息,并给生产者反馈消息
@JmsListener(destination = "mytest.queue")
@SendTo("out.queue")
public String receiveQueue(String text) {
System.out.println("消费者2收到生产者的报文为:"+text);
return "消费者2回复生产者: 收到消息,"+text;
}
}
(6)、创建junit测试类,模拟生产者发布消息
import javax.jms.Destination;
import org.apache.activemq.command.ActiveMQQueue;
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.SpringRunner;
import com.zw.Boot1Start;
import com.zw.jms.Producer;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Boot1Start.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SpringbootJmsApplicationTests {
// 注入自定义的生产者
@Autowired
private Producer producer;
@Test
public void contextLoads() throws InterruptedException {
// 定义生产者发布信息的渠道mytest.queue消息队列
Destination destination = new ActiveMQQueue("mytest.queue");
// 生产者发布信息
for(int i=0; i<100; i++){
producer.sendMessage(destination, "myname is 张三!!!"+i);
}
}
}
(7)、测试结果
(8)、查看消息队列
浏览器输入http://localhost:8161/admin/,用户名和密码都是admin,点击横排的Queues,可查看使用消息队列的情况。
- Number Of Pending Messages:消息队列中待处理的消息
- Number Of Consumers:消费者的数量
- Messages Enqueued:累计进入过消息队列的总量
- Messages Dequeued:累计消费过的消息总量
3、说明
本例中,共一个生产者,两个消费者,两个消息队列(mytest.queue和out.queue)。生产者将消息推到消息队列mytest.queue中,消费者通过监听消息队列mytest.queue,从而获取生产者的消息。消费者也可以在监听的同时将反馈消息通过out.queue消息队列返给生产者,此时生产者既可以(mytest.queue)生产,也可以(out.queue)消费。
本例模式点对点模式,相当于卖火车票,生产出来的一个东西只能被众多消费者中的一个给消费掉。