第一步安装erlang环境:
下载:
由于rabbitmq是erlang来写的,所以需要安装erlang环境:
https://www.erlang-solutions.com/resources/download.html
安装:
yum -y install esl-erlang_23.0.2-1_centos_7_amd64.rpm
检测erlang:
erl
第二步安装RabbitMQ
下载:
http://www.rabbitmq.com/download.html
安装rabbitmq:
yum -y install rabbitmq-server-3.8.5-1.el7.noarch.rpm
查看rabbitmq的插件:
rabbitmq-plugins list
使用命令安装rabbitmq管理插件:rabbitmq-plugins enable rabbitma_management
启动rabbitmq:systemctl start rabbitmq-server.service
查看rabbitmq状态:systemctl status rabbitmq-server.service
访问ip:15672
用户名密码默认guest
出现警告:User can only log in via localhost
解决方法:
cd /etc/rabbitmq/
创建: vim rabbitmq.config
添加:
[{rabbit,[{loopback_users,[]}]}].
重启rabbitmq:systemctl restart rabbitmq-server.service
记得开放服务器防火墙和安全组的端口号!!!
管控台插件页面:
第三步整合springboot
创建springboot项目添加依赖:
<!--amqp依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
application.yml添加配置:
#RabbitMq
rabbitmq:
#服务器
host: *.*.*.*
#用户名
username: guest
#密码
password: guest
#虚拟主机
virtual-host: /
#端口
port: 5672
listener:
simple:
#消费者最小数量
concurrency: 10
#消费者最大数量
max-concurrency: 10
#限制消费者每次只处理一条消息,处理完再继续下一条消息
prefetch: 1
#启动时是否默认启动容器,默认true
auto-startup: true
#被拒绝时重新进入队列
default-requeue-rejected: true
template:
retry:
#发布重试,默认false
enabled: true
#重试时间,默认1000ms
initial-interval: 1000ms
#重试最大次数,默认3次
max-attempts: 3
#重试最大间隔时间
max-interval: 10000ms
#重试的间隔乘数 比如2.0 第一次就等10s 第二次就等20s,第三次就等40s
multiplier: 1
hello入门案例:
创建rabbitmq配置类:RabbitMQConfig
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @description: Rabbitmq配置类 生产者---队列---消费者
* @author
* @date 2022/2/17 16:33
* @version 1.0
*/
@Configuration
public class RabbitMQConfig {
@Bean
public Queue queue(){
return new Queue("queue",true);
}
}
创建生产者:MQSender
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @description: TODO
* @author 孙
* @date 2022/2/17 16:38
* @version 1.0
*/
@Service
@Slf4j
public class MQSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(Object msg){
log.info("发送消息"+msg);
rabbitTemplate.convertAndSend("queue",msg);
}
}
创建接收者:MQReceiver
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @description: 接收者
* @author 孙
* @date 2022/2/17 16:41
* @version 1.0
*/
@Service
@Slf4j
public class MQReceiver {
@RabbitListener(queues = "queue")
public void receive(Object msg){
log.info("接收消息:"+ msg);
}
}
编写测试接口:
/**
* @description: mq测试
* @param:
* @return:
* @author 孙
* @date: 2022/2/17 16:46
*/
@RequestMapping("/mq")
@ResponseBody
public void mq(){
mqSender.send("Hello");
}
在rabbitmq控制台就会有数据显示:
fanout模式
RabbitMQConfig配置类:
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @description: Rabbitmq配置类 生产者---队列---消费者
* @author
* @date 2022/2/17 16:33
* @version 1.0
*/
@Configuration
public class RabbitMQConfig {
//fanout模式创建队列与交换机
private static final String Queue01="queue_fanout01";
private static final String Queue02="queue_fanout02";
private static final String EXCHANGE="fanoutExchange";
@Bean
public Queue queue(){
return new Queue("queue",true);
}
//创建队列与交换机实例
@Bean
public Queue queue01(){
return new Queue(Queue01);
}
@Bean
public Queue queue02(){
return new Queue(Queue02);
}
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange(EXCHANGE);
}
//交换机与队列进行绑定
@Bean
public Binding binding01(){
return BindingBuilder.bind(queue01()).to(fanoutExchange());
}
@Bean
public Binding binding02(){
return BindingBuilder.bind(queue02()).to(fanoutExchange());
}
}
生产者MQSender 生产者向交换机发送消息:
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @description: TODO
* @author 孙
* @date 2022/2/17 16:38
* @version 1.0
*/
@Service
@Slf4j
public class MQSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(Object msg){
log.info("发送消息"+msg);
rabbitTemplate.convertAndSend("queue",msg);
}
public void send02(Object msg){//使用交换机向队列推送消息
log.info("发送消息"+msg);
rabbitTemplate.convertAndSend("fanoutExchange","",msg);
}
}
接收者MQReceiver :
/**
* @description: 接收者
* @author 孙
* @date 2022/2/17 16:41
* @version 1.0
*/
@Service
@Slf4j
public class MQReceiver {
@RabbitListener(queues = "queue")
public void receive(Object msg){
log.info("接收消息:"+ msg);
}
//获取队列中的消息
@RabbitListener(queues = "queue_fanout01")
public void receive01(Object msg){
log.info("QUEUE01接收消息:"+msg);
}
//获取队列中的消息
@RabbitListener(queues = "queue_fanout02")
public void receive02(Object msg){
log.info("QUEUE接收消息:"+msg);
}
}
测试:
/**
* @description: fanout模式
* @param: []
* @return: void
* @author 孙
* @date: 2022/2/18 11:35
*/
@RequestMapping("/mq/fanout")
@ResponseBody
public void mq01() {
mqSender.send02("Hello");
}
交换机:
队列:
Direct模式:
就是在fanout基础上添加了路由,可以让交换的消息传入到指定的队列中
direct配置类 RabbitMQDirectConfig :
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @description: rabbitmq的direct模式
* @author 孙
* @date 2022/2/21 11:02
* @version 1.0
*/
@Configuration
public class RabbitMQDirectConfig {
private static final String QUEUE01="queue_direct01";
private static final String QUEUE02="queue_direct02";
private static final String EXCHANGE="directExchange";
private static final String ROUTINGKEY01="queue.red";
private static final String ROUTINGKEY02="queue.green";
@Bean
public Queue queeu01(){
return new Queue(QUEUE01);
}
@Bean
public Queue queue02(){
return new Queue(QUEUE02);
}
@Bean
public DirectExchange directExchange(){
return new DirectExchange(EXCHANGE);
}
//绑定队列交换机路由
@Bean
public Binding binding01(){
return BindingBuilder.bind(queeu01()).to(directExchange()).with(ROUTINGKEY01);
}
@Bean
public Binding binding02(){
return BindingBuilder.bind(queue02()).to(directExchange()).with(ROUTINGKEY02);
}
}
发送消息:
//direct模式:引入交换机队列路由,根据路由发送到指定的队列中
public void send03(Object msg){
log.info("发送red消息"+msg);
rabbitTemplate.convertAndSend("directExchange","queue.red",msg);
}
public void send04(Object msg){
log.info("发送green消息"+msg);
rabbitTemplate.convertAndSend("directExchange","queue.green",msg);
}
接收消息
@RabbitListener(queues = "queue_direct01")
public void receive03(Object msg){
log.info("QUEUE01接收消息"+msg);
}
@RabbitListener(queues = "queue_direct02")
public void receive04(Object msg){
log.info("QUEUE02接收消息"+msg);
}
topic模式
对direct模式的加强,路由可以使用匹配符进行匹配(#匹配0个或者无数个,*匹配1个)
topic配置类:RabbitMQTopicConfig
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @description: MQ的topic模式
* @author 孙
* @date 2022/2/23 16:03
* @version 1.0
*/
@Configuration
public class RabbitMQTopicConfig {
private static final String QUEUE01="queue_topic01";
private static final String QUEUE02="queue_topic02";
private static final String EXCHANGE="topicExchange";
private static final String ROUTINGKEY01="#.queue.#";//#匹配0个或者无数个
private static final String ROUTINGKEY02="*.queue.#";//*匹配1个
@Bean
public Queue queue01(){
return new Queue(QUEUE01);
}
@Bean
public Queue queue02(){
return new Queue(QUEUE02);
}
@Bean
public TopicExchange topicExchange(){
return new TopicExchange(EXCHANGE);
}
@Bean
public Binding binding01(){
return BindingBuilder.bind(queue01()).to(topicExchange()).with(ROUTINGKEY01);
}
@Bean
public Binding binding02(){
return BindingBuilder.bind(queue02()).to(topicExchange()).with(ROUTINGKEY02);
}
}
发送:MQSender
public void send05(Object msg){
log.info("发送消息(QUEUE01接收):"+msg);
rabbitTemplate.convertAndSend("topicExchange","queue.red.msg",msg);
}
public void send06(Object msg){
log.info("发送消息(QUEUE02接收):"+msg);
rabbitTemplate.convertAndSend("topicExchange","msg.queue.green.abc");
}
Header模式
配置类:
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @description: TODO
* @author 孙
* @date 2022/2/23 16:38
* @version 1.0
*/
@Configuration
public class RabbitMQHeadersConfig {
private static final String QUEUE01="queue_header01";
private static final String QUEUE02="queue_header02";
private static final String EXCHANGE="headerExchange";
@Bean
public Queue queue01(){
return new Queue(QUEUE01);
}
@Bean
public Queue query02(){
return new Queue(QUEUE02);
}
@Bean
public HeadersExchange headersExchange(){
return new HeadersExchange(EXCHANGE);
}
@Bean
public Binding binding01(){
Map<String,Object> map=new HashMap<>();
map.put("color","red");
map.put("speed","low");
return BindingBuilder.bind(queue01()).to(headersExchange()).whereAny(map).match();//任意匹配
}
@Bean
public Binding binding02(){
HashMap<String, Object> map = new HashMap<>();
map.put("color","red");
map.put("speed","fast");
return BindingBuilder.bind(query02()).to(headersExchange()).whereAll(map).match();//匹配全部
}
}
发送消息
public void send07(String msg){
log.info("发送消息被两个queue接收:"+msg);
MessageProperties properties = new MessageProperties();
properties.setHeader("color","red");
properties.setHeader("speed","normal");
Message message = new Message(msg.getBytes(),properties);
rabbitTemplate.convertAndSend("headerExchange","",message);
}
public void send08(String msg){
log.info("发送消息被1个queue接收:"+msg);
MessageProperties properties = new MessageProperties();
properties.setHeader("color","red");
properties.setHeader("speed","fast");
Message message = new Message(msg.getBytes(),properties);
rabbitTemplate.convertAndSend("headerExchange","",message);
}
接收消息
@RabbitListener(queues = "queue_header01")
public void receive07(Message msg){
log.info("QUEUE01接收消息"+msg);
log.info("QUEUE01接收消息"+new String(msg.getBody()));
}
@RabbitListener(queues = "queue_header02")
public void receive08(Message msg){
log.info("QUEUE02接收消息:"+msg);
log.info("QUEUE02接收消息"+new String(msg.getBody()));
}
测试
@RequestMapping("/mq/header01")
@ResponseBody
public void mq07(){
mqSender.send07("hello red");
}
@RequestMapping("/mq/header02")
@ResponseBody
public void mq08(){
mqSender.send08("hello green");
}