实现消息队列有多种框架,例如ActiveMQ、RabbitMQ、RocketMQ和Kafka,本文选择使用RabbitMQ实现简单的消息队列。
1 安装RabbitMQ
1.1 安装Erlang
下载Erlang,下载地址
https://www.erlang.org/downloads
默认安装即可(安装目录可自己选择)
1.2 安装RabbitMQ
(1)下载RabbitMQ,下载地址
https://www.rabbitmq.com/download.html
默认安装即可(安装目录可自己选择)
(2)安装和配置插件
先进入rabbitmq的sbin目录,再进入cmd,输入如下命令
rabbitmq-plugins enable rabbitmq_management
(3)查看RabbitMQ是否安装成功
输入以下命令
rabbitmqctl status
(3)启动RabbitMQ
(4)进入RabbitMQ
在浏览器中输入地址:http://127.0.0.1:15672/#/
初始化账号:guest,密码:guest
2 SpringBoot实现RabbitMQ
简单实现了Direct Exchange、Fanout Exchange、Topic Exchange三种消息模式
github地址:https://github.com/MasonYyp/rabbitmq
工程目录如下:
运行结果如下:
2.1 DirectModel
(1)ConfigQueueDirect
package com.example.mq.service.DirectModel;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConfigQueueDirect {
// 管理员消息队列
@Bean
public Queue createAdmin(){
// 创建消息队列,true代表持久化
return new Queue("adminDirect", true);
}
// 用户消息队列
@Bean
public Queue createUser(){
return new Queue("userDirect", true);
}
}
(2)MessageConsumerDirect
package com.example.mq.service.DirectModel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
/*
* 消息消费者
* */
@Service
public class MessageConsumerDirect {
@RabbitListener(queues = "adminDirect")
public void adminReceiveMsg(String msg){
System.out.println("adminDirect 消费者收到消息 "+msg);
}
@RabbitListener(queues = "userDirect")
public void userReceiveMsg(String msg){
System.out.println("userDirect 消费者收到消息 "+msg);
}
}
(3)MessageProducerDirect
package com.example.mq.service.DirectModel;
import com.example.mq.util.MessageProducerInter;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/*
* 消息生成者
* */
@Service("messageProducerDirect")
public class MessageProducerDirect implements MessageProducerInter, ConfirmCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void adminSend(String msg) {
System.out.println("adminDirect 生产者发送信息 "+msg);
// 回调
this.rabbitTemplate.setConfirmCallback(this);
this.rabbitTemplate.convertAndSend("adminDirect", msg);
}
@Override
public void userSend(String msg) {
System.out.println("userDirect 生产者发送信息 "+msg);
// 回调
this.rabbitTemplate.setConfirmCallback(this);
this.rabbitTemplate.convertAndSend("userDirect", msg);
}
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
// 确认接收成功
if(ack){
System.out.println("Message 接收成功!");
}else {
System.out.println("Message 接收失败!" + cause);
}
}
}
2.2 TopicModel
(1)ConfigQueueTopic
package com.example.mq.service.TopicModel;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConfigQueueTopic {
// 管理员消息队列
@Bean(name = "adminQue")
public Queue createAdmin(){
// 创建消息队列,true代表持久化
return new Queue("adminTopic", true);
}
// 用户消息队列
@Bean(name = "userQue")
public Queue createUser(){
return new Queue("userTopic", true);
}
// 创建交换机
@Bean
public TopicExchange exchange(){
return new TopicExchange("exchange");
}
// 绑定交换机
@Bean
public Binding bindingAdminExchangeMessage(@Qualifier("adminQue") Queue message, TopicExchange exchange){
return BindingBuilder.bind(message).to(exchange).with("adminTopic");
}
@Bean
public Binding bindingUserExchangeMessage(@Qualifier("userQue") Queue message, TopicExchange exchange){
return BindingBuilder.bind(message).to(exchange).with("userTopic");
}
}
(2)MessageConsumerTopic
package com.example.mq.service.TopicModel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/*
* 消息消费者
* */
@Service
public class MessageConsumerTopic {
@RabbitListener(queues = "adminTopic")
public void adminReceiveMsg(String msg){
System.out.println("admin 消费者收到消息 topic "+msg);
}
@RabbitListener(queues = "userTopic")
public void userReceiveMsg(String msg){
System.out.println("user 消费者收到消息 topic "+msg);
}
}
(3)MessageProducerTopic
package com.example.mq.service.TopicModel;
import com.example.mq.util.MessageProducerInter;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/*
* 消息生成者
* */
@Service("messageProducerTopic")
public class MessageProducerTopic implements MessageProducerInter, ConfirmCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void adminSend(String msg) {
System.out.println("admin 生产者发送信息 topic "+msg);
// 回调
this.rabbitTemplate.setConfirmCallback(this);
this.rabbitTemplate.convertAndSend("adminTopic", msg);
}
@Override
public void userSend(String msg) {
System.out.println("user 生产者发送信息 topic "+msg);
// 回调
this.rabbitTemplate.setConfirmCallback(this);
this.rabbitTemplate.convertAndSend("userTopic", msg);
}
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
// 确认接收成功
if(ack){
System.out.println("Message 接收成功!");
}else {
System.out.println("Message 接收失败!" + cause);
}
}
}
2.3 FanoutModel
(1)ConfigQueueFanout
package com.example.mq.service.FanoutModel;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConfigQueueFanout {
// 管理员消息队列
@Bean(name = "adminQueFanout")
public Queue createAdmin(){
// 创建消息队列,true代表持久化
return new Queue("adminFanout", true);
}
// 用户消息队列
@Bean(name = "userQueFanout")
public Queue createUser(){
return new Queue("userFanout", true);
}
// 创建路由器
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("fanoutExchange");
}
// 绑定路由器
@Bean
public Binding bindingAdminFanoutExchangeMessage(@Qualifier("adminQueFanout") Queue message, FanoutExchange fanoutExchange){
// 不绑定key
return BindingBuilder.bind(message).to(fanoutExchange);
}
@Bean
public Binding bindingUserFanoutExchangeMessage(@Qualifier("userQueFanout") Queue message, FanoutExchange fanoutExchange){
return BindingBuilder.bind(message).to(fanoutExchange);
}
}
(2)MessageConsumerFanout
package com.example.mq.service.FanoutModel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/*
* 消息消费者
* */
@Service
public class MessageConsumerFanout {
@RabbitListener(queues = "adminFanout")
public void adminReceiveMsg(String msg){
System.out.println("adminFanout 消费者收到消息 "+msg);
}
@RabbitListener(queues = "userFanout")
public void userReceiveMsg(String msg){
System.out.println("userFanout 消费者收到消息 "+msg);
}
}
(3)MessageProducerFanout
package com.example.mq.service.FanoutModel;
import com.example.mq.util.MessageProducerInter;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/*
* 消息生成者
* */
@Service("messageProducerFanout")
public class MessageProducerFanout implements MessageProducerInter, ConfirmCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void adminSend(String msg) {
System.out.println("adminFanout 生产者发送信息 "+msg);
// 回调
this.rabbitTemplate.setConfirmCallback(this);
this.rabbitTemplate.convertAndSend("adminFanout", msg);
}
@Override
public void userSend(String msg) {
System.out.println("userFanout 生产者发送信息 "+msg);
// 回调
this.rabbitTemplate.setConfirmCallback(this);
this.rabbitTemplate.convertAndSend("userFanout", msg);
}
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
// 确认接收成功
if(ack){
System.out.println("Message 接收成功!");
}else {
System.out.println("Message 接收失败!" + cause);
}
}
}
(4)MessageQueFanoutTest
package com.example.mq;
import com.example.mq.util.MessageProducerInter;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class MessageQueFanoutTest {
@Autowired
@Qualifier("messageProducerFanout")
private MessageProducerInter messageProducer;
@Test
public void test() throws InterruptedException {
for (int i=0; i<10; i++){
this.messageProducer.adminSend(" "+i);
this.messageProducer.userSend(" "+i);
Thread.sleep(1000);
}
}
}