SpringBoot整合RabbitMQ消息队列
1.RabbitMQ简介RabbitMQ是一套开源的消息队列服务软件,实现了高级消息队列协议(AMQP),服务器采用Erlang语言开发,支持多种客户端,如:Python、Ruby、Java、JMS、C#、PHP、JavaScript等。2.Erlang安装(1)安装RabbitMQ需要先安装Erlang语言开发包,官网下载地址:https://www.erlang.org...
1.RabbitMQ简介
RabbitMQ是一套开源的消息队列服务软件,实现了高级消息队列协议(AMQP),服务器采用Erlang语言开发,支持多种客户端,如:Python、Ruby、Java、JMS、C#、PHP、JavaScript等。
2.Erlang安装
(1)安装RabbitMQ需要先安装Erlang语言开发包,官网下载地址:https://www.erlang.org/downloads
(2)配置环境变量:
新建系统变量:ERLANG_HOME= E:\erl10.5
添加到PATH: %ERLANG_HOME%\bin;
打开cmd命令框,输入命令:erl
如上图所示,则安装成功
注意:安装RabbitMQ需要与Erlang版本对应,否则会安装失败。
查看版本对应关系地址:https://www.rabbitmq.com/which-erlang.html
3.RabbitMQ安装
(1)官网下载地址:https://www.rabbitmq.com/download.html
(2)配置环境变量:
新建系统变量:RABBITMQ_SERVER:E:\RabbitMQ Server\rabbitmq_server-3.8.1
添加到PATH: %RABBITMQ_SERVER%\sbin;
打开cmd命令框,输入命令:rabbitmq-plugins enable rabbitmq_management
如上图所示,则安装成功,并激活了RabbitMQ可视化管理插件
安装系统服务:rabbitmq-service install
启动系统服务:rabbitmq-service start
启动服务后,访问地址:localhost:15672
如上图所示,则启动成功。默认账号:guest,默认密码:guest
注意:RabbitMQ修改日志和数据的存放路径默认为C盘的\Users\Administrator\AppData\Roaming\RabbitMQ路径下,该路径不能包含中文,否则会启动服务失败,若包含中文,可配置系统变量RABBITMQ_BASE来手动指定数据存放目录。
如:RABBITMQ_BASE:E:\RabbitMQ Server\rabbitmq_server-3.8.1\data
4.pom.xml添加RabbitMQ依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
5.application.properties添加RabbitMQ配置
#RabbitMQ配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
#消费者数量
spring.rabbitmq.listener.simple.concurrency=10
#最大消费者数量
spring.rabbitmq.listener.simple.max-concurrency=10
#消费者每次从队列获取的消息数量。写多了,如果长时间得不到消费,数据就一直得不到处理
spring.rabbitmq.listener.simple.prefetch=1
#消费者自动启动
spring.rabbitmq.listener.auto-startup=true
#消费者消费失败,自动重新入队
spring.rabbitmq.listener.simple.default-requeue-rejected=true
#启用发送重试 队列满了发不进去时启动重试
spring.rabbitmq.template.retry.enabled=true
#1秒钟后重试一次
spring.rabbitmq.template.retry.initial-interval=1000
#最大重试次数 3次
spring.rabbitmq.template.retry.max-attempts=3
#最大间隔 10s
spring.rabbitmq.template.retry.max-interval=10000
#等待间隔 的倍数。如果为2 第一次 乘以2 等1秒, 第二次 乘以2 等2秒 ,第三次 乘以2 等4秒
spring.rabbitmq.template.retry.multiplier=1.0
6.创建RabbitMQ配置类
import java.util.HashMap;
import java.util.Map;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.HeadersExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MQConfig {
//Direct模式
public static final String QUEUE="queue";
//Topic模式
public static final String TOPIC_QUEUE1="topic.queue1";
public static final String TOPIC_QUEUE2="topic.queue2";
public static final String TOPIC_EXCHANGE="topic.exchange";
public static final String ROUTINIG_KEY1="topic.key1";
public static final String ROUTINIG_KEY2="topic.#";
//Fanout模式
public static final String FANOUT_QUEUE1="fanout.queue1";
public static final String FANOUT_QUEUE2="fanout.queue2";
public static final String FANOUT_EXCHANGE="fanout.exchange";
//Header模式
public static final String HEADER_QUEUE="header.queue";
public static final String HEADER_EXCHANGE="header.exchange";
/**
* Direct模式
*/
@Bean
public Queue queue() {
//名称,是否持久化
return new Queue(QUEUE,true);
}
/**
* Topic模式
*/
@Bean
public Queue topicqueue1() {
//名称,是否持久化
return new Queue(TOPIC_QUEUE1,true);
}
@Bean
public Queue topicqueue2() {
//名称,是否持久化
return new Queue(TOPIC_QUEUE2,true);
}
//先将消息放到exchange中去,再把消息放到queue里面去
@Bean
public TopicExchange topicExchange() {
//名称
return new TopicExchange(TOPIC_EXCHANGE);
}
@Bean
public Binding topicBinding1() {
//绑定到某一个queue上面
return BindingBuilder.bind(topicqueue1()).to(topicExchange()).with(ROUTINIG_KEY1);//"topic.key1"
}
@Bean
public Binding topicBinding2() {
//绑定到某一个queue上面
return BindingBuilder.bind(topicqueue2()).to(topicExchange()).with(ROUTINIG_KEY2);//"topic.#" #匹配一个或者多个字符
}
/**
* Fanout模式(广播模式)
*/
@Bean
public Queue fanoutqueue1() {
//名称,是否持久化
return new Queue(FANOUT_QUEUE1,true);
}
@Bean
public Queue fanoutqueue2() {
//名称,是否持久化
return new Queue(FANOUT_QUEUE2,true);
}
@Bean
public FanoutExchange fanoutExchange() {
//名称
return new FanoutExchange(FANOUT_EXCHANGE);
}
@Bean
public Binding fanoutBinding1() {
//绑定到某一个queue上面
return BindingBuilder.bind(fanoutqueue1()).to(fanoutExchange());//广播,没有key的
}
@Bean
public Binding fanoutBinding2() {
//绑定到某一个queue上面
return BindingBuilder.bind(fanoutqueue2()).to(fanoutExchange());//广播,没有key的
}
/**
* Header模式
*/
@Bean
public Queue headerQueue1() {
//名称,是否持久化
return new Queue(HEADER_QUEUE,true);
}
@Bean
public HeadersExchange headersExchange() {
//名称
return new HeadersExchange(HEADER_EXCHANGE);
}
/**
* headerbinding
* 在这个message里面,会有一个head部分,必须完全满足map里面的key-value,才能放到队列中
*/
@Bean
public Binding headerBinding() {
//绑定到某一个queue上面
Map<String,Object> map=new HashMap<String,Object>();
map.put("header1","value1");
map.put("header2","value2");
return BindingBuilder.bind(headerQueue1()).to(headersExchange()).whereAll(map).match();
}
}
7.创建RabbitMQ生产者
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
//生产者
@Service
public class MQSender {
@Autowired
AmqpTemplate amqpTemplate;
//Direct模式
public void send(String msg) {
System.out.println("Direct模式发送消息>>>:"+msg);
//第一个参数队列的名字,第二个参数发出的信息
amqpTemplate.convertAndSend(MQConfig.QUEUE, msg);
}
//Topic模式
public void sendTopic(Object msg) {
System.out.println("Topic模式发送消息>>>:"+msg);
amqpTemplate.convertAndSend(MQConfig.TOPIC_EXCHANGE,"topic.key1",msg+"1");
amqpTemplate.convertAndSend(MQConfig.TOPIC_EXCHANGE,"topic.key2",msg+"2");
}
//Fanout模式
public void sendFanout(Object msg) {
System.out.println("Fanout模式发送消息>>>:"+msg);
//广播,不需要key
amqpTemplate.convertAndSend(MQConfig.FANOUT_EXCHANGE,"",msg);
}
//Header模式
public void sendHeader(String msg) {
System.out.println("Header模式发送消息>>>:"+msg);
//properties设置Header需要跟绑定的map完全一致,才能放到队列中
MessageProperties properties=new MessageProperties();
properties.setHeader("header1", "value1");
properties.setHeader("header2", "value2");
Message obj=new Message(msg.getBytes(),properties);
//传入一个message的对象,不需要key
amqpTemplate.convertAndSend(MQConfig.HEADER_EXCHANGE, "", obj);
}
}
8.创建RabbitMQ消费者
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
//消费者
@Service
public class MQReceiver {
@RabbitListener(queues=MQConfig.QUEUE)//指明监听的是哪一个queue
public void receive(String msg) {
System.out.println("Direct模式接收消息:"+msg);
}
@RabbitListener(queues=MQConfig.TOPIC_QUEUE1)//指明监听的是哪一个queue
public void receiveTopic1(String msg) {
System.out.println("Topic模式1接收消息:"+msg);
}
@RabbitListener(queues=MQConfig.TOPIC_QUEUE2)//指明监听的是哪一个queue
public void receiveTopic2(String msg) {
System.out.println("Topic模式2接收消息:"+msg);
}
@RabbitListener(queues=MQConfig.FANOUT_QUEUE1)//指明监听的是哪一个queue
public void receiveFanout1(String msg) {
System.out.println("Fanout模式1接收消息:"+msg);
}
@RabbitListener(queues=MQConfig.FANOUT_QUEUE2)//指明监听的是哪一个queue
public void receiveFanout2(String msg) {
System.out.println("Fanout模式2接收消息:"+msg);
}
@RabbitListener(queues=MQConfig.HEADER_QUEUE)//指明监听的是哪一个queue
public void receiveHeader(byte[] msg) {
System.out.println("Header模式接收消息:"+new String(msg));
}
}
9.测试发送消息
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.com.app.rabbitmq.MQSender;
@Controller
public class Test {
@Autowired
private MQSender sender;
@RequestMapping("/sendMsg")
@ResponseBody
public void sendMsg() throws Exception {
//Direct模式
sender.send("Direct Hello");
//Topic模式
sender.sendTopic("Topic Hello");
//Fanout模式
sender.sendFanout("Fanout Hello");
//Header模式
sender.sendHeader("Header Hello");
}
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)