Linux 版本
cat /proc/version
# 添加仓库
curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
Detected operating system as centos/8.
# 安装erlang
dnf install erlang
# 安装完成后可以查看下版本测试是否成功安装
erl -v
RabbitMQ 国内镜像源加速下载:
https://mirrors.huaweicloud.com/rabbitmq-server/
# 解压
rpm -Uvh rabbitmq-server-3.10.2-1.el8.noarch.rpm
# 安装 socket(rabbitmq安装需要)
yum install -y socket
# 安装 rabbitmq
yum install -y rabbitmq-server
# 启动
systemctl start rabbitmq-server
# 查看状态
systemctl status rabbitmq-server
其他命令
systemctl enable rabbitmq-server
systemctl stop rabbitmq-server
systemctl restart rabbitmq-server
安装 Web 插件
rabbitmq-plugins enable rabbitmq_management
开启用户远程访问
cd /etc/rabbitmq
touch rabbitmq.conf
vim rabbitmq.conf
rabbitmq.conf内容
{loopback_users, []}
然后需要去云服务器开启相应的端口(安全组规则)
需要开启的端口 15672(Web访问) 和 5672(amqp)
然后访问RabbitMQ Web
http://localhost:15672
配置之后可以使得guest用户能够被远程访问
使用默认账号进入 guest , guest
到此完成了 RabbitMQ 的安装和启动
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-amqpartifactId>
dependency>
RabbitMQ有五种交换机模式,defalut,direct,fanout,headers,topic
默认就是只需要创建一个队列,然后往队列里发送。
package com.hwh.killer.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @description: 消息队列配置类
* @author: HWH
* @create: 2022-06-13 19:46
**/
@Configuration
public class RabbitMQFanoutConfig {
@Bean
public Queue queue(){
return new Queue("queue", true);
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @description: 消息队列发送者
* @author: HWH
* @create: 2022-06-13 19:49
**/
@Service
@Slf4j
public class MQSender {
@Resource
private RabbitTemplate rabbitTemplate;
public void sendDefalut(Object msg){
log.info("发送消息:" + msg);
// 发送到队列
rabbitTemplate.convertAndSend("queue", msg);
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @description: 消息队列接收者
* @author: HWH
* @create: 2022-06-13 19:50
**/
@Service
@Slf4j
public class MQReceiver {
@RabbitListener(queues = "queue")
public void receive(Object msg){
log.info("接收消息:" + msg);
}
}
package com.hwh.killer.controller;
import com.hwh.killer.common.ApiResult;
import com.hwh.killer.rabbitmq.MQSender;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
* @description:
* @author: HWH
* @create: 2022-06-10 11:10
**/
@Controller
@RequestMapping("/user")
@Api(tags = "MQ测试模块")
public class UserController {
@Resource
MQSender mqSender;
/**
* 测试发送 RabbitMQ 消息
* */
@ApiOperation(value = "测试消息队列接口", httpMethod = "GET", notes = "消息队列发送接受测试")
@GetMapping("/mq")
@ResponseBody
public void mq(){
mqSender.sendDefalut("hello");
}
}
Fanout就相当于创建多个队列,需要有一个管理者,交换机,Fanout交换机来决定消息应该去到哪一个队列,但是目前会把消息与该交换机绑定的所有队列中,也叫广播模式,类似于发布订阅,队列只要订阅了当前交换机,那么消息发送过来的时候,会给订阅者都发送消息
package com.hwh.killer.config;
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: 消息队列配置类
* @author: HWH
* @create: 2022-06-13 19:46
**/
@Configuration
public class RabbitMQFanoutConfig {
private static final String QUEUE01 = "queue_fanout01";
private static final String QUEUE02 = "queue_fanout02";
private static final String EXCHANGE = "fanoutExchange";
/**
* Fanout 模式 (广播模式,类似于发布订阅)
* 不处理路由键,只需要简单的将队列绑定到交换机上
* 发送交换机的消息都会被转发到与该交换机绑定的所有队列上
* Fanout交换机转发消息是最快的
* */
@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());
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @description: 消息队列发送者
* @author: HWH
* @create: 2022-06-13 19:49
**/
@Service
@Slf4j
public class MQSender {
@Resource
private RabbitTemplate rabbitTemplate;
public void sendFanout(Object msg){
log.info("Fanout发送消息:" + msg);
// 发送到交换机
rabbitTemplate.convertAndSend("fanoutExchange","", msg);
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @description: 消息队列接收者
* @author: HWH
* @create: 2022-06-13 19:50
**/
@Service
@Slf4j
public class MQReceiver {
@RabbitListener(queues = "queue_fanout01")
public void receive01(Object msg){
log.info("QUEUE01接收消息:" + msg);
}
@RabbitListener(queues = "queue_fanout02")
public void receive02(Object msg){
log.info("QUEUE02接收消息:" + msg);
}
}
package com.hwh.killer.controller;
import com.hwh.killer.common.ApiResult;
import com.hwh.killer.rabbitmq.MQSender;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
* @description:
* @author: HWH
* @create: 2022-06-10 11:10
**/
@Controller
@RequestMapping("/user")
@Api(tags = "MQ测试模块")
public class UserController {
@Resource
MQSender mqSender;
/**
* 测试发送 RabbitMQ 消息
* */
@ApiOperation(value = "测试消息队列接口", httpMethod = "GET", notes = "消息队列发送接受测试")
@GetMapping("/mq")
@ResponseBody
public void mq(){
mqSender.sendFanout("hello");
}
}
dirct相比 Fanout 就是多了一个路由键绑定,也就是相当于指定了一条走向队列的路径,不再是广播式地向每一个队列都发送消息,而是多了个路由键指定要向哪一个队列发送消息。问题是队列多了之后,路由键也多,会显得很繁琐。
package com.hwh.killer.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @description: 路由键模式配置文件
* @author: HWH
* @create: 2022-06-13 23:24
**/
@Configuration
public class RabbiMQDirectConfig {
/**
* direct 模式
* 绑定路由键,指定的路由键走向相应的队列
* */
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 queue01(){
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(queue01()).to(directExchange()).with(ROUTINGKEY01);
}
@Bean
public Binding binding02(){
return BindingBuilder.bind(queue02()).to(directExchange()).with(ROUTINGKEY02);
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @description: 消息队列发送者
* @author: HWH
* @create: 2022-06-13 19:49
**/
@Service
@Slf4j
public class MQSender {
@Resource
private RabbitTemplate rabbitTemplate;
public void sendDirect(Object msg, String router){
log.info(router + "发送消息:" + msg);
rabbitTemplate.convertAndSend("directExchange", router, msg);
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @description: 消息队列接收者
* @author: HWH
* @create: 2022-06-13 19:50
**/
@Service
@Slf4j
public class MQReceiver {
@RabbitListener(queues = "queue_direct01")
public void receive03(Object msg){
log.info("direct01接收消息:" + msg);
}
@RabbitListener(queues = "queue_direct02")
public void receive04(Object msg){
log.info("direct02接收消息:" + msg);
}
}
package com.hwh.killer.controller;
import com.hwh.killer.common.ApiResult;
import com.hwh.killer.rabbitmq.MQSender;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
* @description:
* @author: HWH
* @create: 2022-06-10 11:10
**/
@Controller
@RequestMapping("/user")
@Api(tags = "MQ测试模块")
public class UserController {
@Resource
MQSender mqSender;
/**
* 测试发送 RabbitMQ 消息
* */
@ApiOperation(value = "测试消息队列接口", httpMethod = "GET", notes = "消息队列发送接受测试")
@GetMapping("/mq")
@ResponseBody
public void mq(){
mqSender.sendDirect("hello");
}
}
Topic 相当于在 Direct 的基础上,多了一个模糊搜索的功能
“*” 匹配一个单词,比如 *.orange.* 匹配:quick.orange.rabbit
“#” 匹配零个或多个词 比如 lazy.# 匹配:lazy.brown.for
也就可以向一个类型的消息队列发送消息了。
package com.hwh.killer.config.rabbitmqThymleaf;
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: 标题模式
* @author: HWH
* @create: 2022-06-13 23:36
**/
@Configuration
public class RabbiMQTopicConfig {
/**
* topic 模式
* 绑定路由键,指定的路由键走向相应的队列
* “*” 匹配一个单词,比如 *.orange.* 匹配:quick.orange.rabbit
* “#” 匹配零个或多个词 比如 lazy.# 匹配:lazy.brown.for
* */
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 = "*.orange.*";
private static final String ROUTINGKEY02 = "lazy.#";
@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);
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @description: 消息队列发送者
* @author: HWH
* @create: 2022-06-13 19:49
**/
@Service
@Slf4j
public class MQSender {
@Resource
private RabbitTemplate rabbitTemplate;
public void sendTopic(Object msg, String router){
log.info(router + "发送消息:" + msg);
rabbitTemplate.convertAndSend("topicExchange", router, msg);
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @description: 消息队列接收者
* @author: HWH
* @create: 2022-06-13 19:50
**/
@Service
@Slf4j
public class MQReceiver {
@RabbitListener(queues = "queue_topic01")
public void receive05(Object msg){
log.info("topic01接收消息:" + msg);
}
@RabbitListener(queues = "queue_topic02")
public void receive06(Object msg){
log.info("topic02接收消息:" + msg);
}
}
package com.hwh.killer.controller;
import com.hwh.killer.common.ApiResult;
import com.hwh.killer.rabbitmq.MQSender;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
* @description:
* @author: HWH
* @create: 2022-06-10 11:10
**/
@Controller
@RequestMapping("/user")
@Api(tags = "MQ测试模块")
public class UserController {
@Resource
MQSender mqSender;
/**
* 测试发送 RabbitMQ 消息
* */
@ApiOperation(value = "测试消息队列接口", httpMethod = "GET", notes = "消息队列发送接受测试")
@GetMapping("/mq")
@ResponseBody
public void mq(){
mqSender.sendFanout("hello");
}
}
比较少用的消息队列模式,相比于其他的,该模式会使用一个Map绑定,通过Map的 key 和 value 来确定消息该发送往哪一个消息队列
package com.hwh.killer.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.HeadersExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @description: Header模式
* @author: HWH
* @create: 2022-06-14 10:54
**/
@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 queue02(){
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", "fast");
return BindingBuilder.bind(queue01()).to(headersExchange()).whereAny(map).match();
}
@Bean
public Binding binding02(){
Map<String, Object> map = new HashMap<>();
map.put("color", "green");
map.put("speed", "slow");
return BindingBuilder.bind(queue02()).to(headersExchange()).whereAny(map).match();
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @description: 消息队列发送者
* @author: HWH
* @create: 2022-06-13 19:49
**/
@Service
@Slf4j
public class MQSender {
@Resource
private RabbitTemplate rabbitTemplate;
public void sendHeader(String msg, String key, String value){
log.info("发送消息:" + msg);
MessageProperties properties = new MessageProperties();
properties.setHeader(key, value);
// 可以设置多个 header 发送
// properties.setHeader(key, value);
Message message = new Message(msg.getBytes(), properties);
rabbitTemplate.convertAndSend("headerExchange", "", message);
}
}
package com.hwh.killer.rabbitmq.thymleaf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @description: 消息队列接收者
* @author: HWH
* @create: 2022-06-13 19:50
**/
@Service
@Slf4j
public class MQReceiver {
@RabbitListener(queues = "queue_header01")
public void receive07(Message msg){
log.info("header01接收Message对象:" + msg);
log.info("header01接收消息:" + msg);
}
@RabbitListener(queues = "queue_header02")
public void receive08(Message msg){
log.info("header02接收Message对象:" + msg);
log.info("header02接收消息:" + msg);
}
}
package com.hwh.killer.controller;
import com.hwh.killer.common.ApiResult;
import com.hwh.killer.rabbitmq.MQSender;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
* @description:
* @author: HWH
* @create: 2022-06-10 11:10
**/
@Controller
@RequestMapping("/user")
@Api(tags = "MQ测试模块")
public class UserController {
@Resource
MQSender mqSender;
/**
* 测试发送 RabbitMQ 消息
* */
@ApiOperation(value = "测试消息队列接口", httpMethod = "GET", notes = "消息队列发送接受测试")
@GetMapping("/mq")
@ResponseBody
public void mq(){
mqSender.sendFanout("hello");
}
}