RabbitMQ 的安装和 集成 SpringBoot简单使用

文章目录

  • 安装
    • 安装 Erling
    • 安装 RabbitMQ
    • 启动RabbitMQ
    • 使用RabbitMQ
  • SpringBoot 集成 RabbitMQ 使用
    • 1、 导入相应的依赖
    • 2. 使用 RabbitMQ
      • Default
        • 配置类
        • 发送消息
        • 接收消息
        • 接口测试
      • Fanout
        • 配置类
        • 发送者
        • 接收者
        • 接口测试
      • Direct
        • 配置类
        • 发送者
        • 接收者
        • 接口测试
      • Topic
        • 配置类
        • 发送者
        • 接收者
        • 接口测试
      • Headers
        • 配置类
        • 发送者
        • 接收者
        • 接口测试

安装

Linux 版本

cat /proc/version

在这里插入图片描述

安装 Erling

# 添加仓库
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

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

启动RabbitMQ

# 启动
systemctl start rabbitmq-server
# 查看状态
systemctl status rabbitmq-server

其他命令

systemctl enable rabbitmq-server
systemctl stop rabbitmq-server
systemctl restart rabbitmq-server

使用RabbitMQ

安装 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用户能够被远程访问
RabbitMQ 的安装和 集成 SpringBoot简单使用_第1张图片
使用默认账号进入 guest , guest

RabbitMQ 的安装和 集成 SpringBoot简单使用_第2张图片

到此完成了 RabbitMQ 的安装和启动

SpringBoot 集成 RabbitMQ 使用

1、 导入相应的依赖

       
       <dependency>
           <groupId>org.springframework.bootgroupId>
           <artifactId>spring-boot-starter-amqpartifactId>
       dependency>

2. 使用 RabbitMQ

RabbitMQ有五种交换机模式,defalut,direct,fanout,headers,topic
RabbitMQ 的安装和 集成 SpringBoot简单使用_第3张图片

Default

默认就是只需要创建一个队列,然后往队列里发送。

配置类
	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就相当于创建多个队列,需要有一个管理者,交换机,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");
    }
}

Direct

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

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");
    }
}

Headers

比较少用的消息队列模式,相比于其他的,该模式会使用一个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");
    }
}

你可能感兴趣的:(消息队列,rabbitmq,spring,boot,linux)