SpringBoot简单整合RabbitMQ

SpringBoot整合RabbitMQ

RabbitMQ简介

RabbitMQ是由erlang开发的AMQP(Advanced Message Queuing Protocol)的开源实现。

核心概念

Message

消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

Publisher

消息的生产者,也是一个向交换器发布消息的客户端应用程序。

Exchange

交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。

Exchange有4种类型:direct(默认),fanout, topic, 和headers,不同类型的Exchange转发消息的策略有所区别

Queue

消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

Binding

绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。

Exchange 和Queue的绑定可以是多对多的关系。

Connection

网络连接,比如一个TCP连接。

Channel

信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。

Consumer

消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。

Virtual Host

虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 “/”。

Broker

表示消息队列服务器实体

运行机制

消息的生产者将消息发布到Exchange上,根据Exchange的类型以及Binding关系,决定Exchange上的消息发送到哪个队列。

Exchange类型

direct

如果消息的路由键与Binding中的bindingKey完全一致,就发送到对应的队列中。

fanout

消息会广播到所有binding的队列中

topic

交换机通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号“#”和符号“#匹配0个或多个单词,*****匹配一个单词。

如binding中有模式dog.#、*.msg,如果给交换机发送一个路由键为dog.msg的消息,那么前面两种模式的队列都会收到这个dog.msg路由键的消息。

headers

匹配 AMQP 消息的 header 而不是路由键, headers 交换器和 direct 交换器的匹配完全一致,但性能差很多,目前几乎用不到了

整合RabbitMQ

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

RabbitMQ服务器连接

(Application.yml)rabbitMQ的默认账号密码是guest/guest

spring:
  rabbitmq:
    host: 192.168.37.100
    port: 5672
    username: guest
    password: guest

测试使用

初步使用RabbitTemplate和RabbitAdmin
package org.fall;

import org.fall.entity.Person;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootAmqpApplicationTests {

    // mq的消息发送和处理组件
    @Autowired
    RabbitTemplate rabbitTemplate;

    // mq的管理组件
    @Autowired
    RabbitAdmin rabbitAdmin;


    /**
     * 使用rabbitAdmin进行交换器、队列、绑定关系等的初始化
     */
    @Test
    void contextLoads() {
        // 创建交换器
        // 传入要创建的交换器的名字
        rabbitAdmin.declareExchange(new DirectExchange("exchange.direct"));
        rabbitAdmin.declareExchange(new FanoutExchange("exchange.fanout"));
        rabbitAdmin.declareExchange(new TopicExchange("exchange.topic"));

        /* 创建队列:
            fall
            fall.other
            fall.msg
            learn.msg
            Queue的构造器中传入要创建的队列的名字
         */

        rabbitAdmin.declareQueue(new Queue("fall"));
        rabbitAdmin.declareQueue(new Queue("fall.other"));
        rabbitAdmin.declareQueue(new Queue("fall.msg"));
        rabbitAdmin.declareQueue(new Queue("learn.msg"));

        // 绑定队列与交换器
        /**
         * Binding构造器的源码:
         *     public Binding(
         *         String destination,                     // 绑定的目标
         *         DestinationType destinationType,        // 绑定的种类(QUEUE/EXCHANGE)
         *         String exchange,                        // 绑定的交换器的名字
         *         String routingKey,                      // 路由键
         *      @Nullable Map<String, Object> arguments)// 传入的参数 ,可以为null
         *      {
         *         // 处理的代码省略
         *      }
         */
        rabbitAdmin.declareBinding(new Binding("fall", Binding.DestinationType.QUEUE, "exchange.direct", "fall",null));
        rabbitAdmin.declareBinding(new Binding("fall.other", Binding.DestinationType.QUEUE, "exchange.direct", "fall.other",null));
        rabbitAdmin.declareBinding(new Binding("fall.msg", Binding.DestinationType.QUEUE, "exchange.direct", "fall.msg",null));
        rabbitAdmin.declareBinding(new Binding("learn.msg", Binding.DestinationType.QUEUE, "exchange.direct", "learn.msg",null));


        rabbitAdmin.declareBinding(new Binding("fall", Binding.DestinationType.QUEUE, "exchange.fanout", "fall",null));
        rabbitAdmin.declareBinding(new Binding("fall.other", Binding.DestinationType.QUEUE, "exchange.fanout", "fall.other",null));
        rabbitAdmin.declareBinding(new Binding("fall.msg", Binding.DestinationType.QUEUE, "exchange.fanout", "fall.msg",null));
        rabbitAdmin.declareBinding(new Binding("learn.msg", Binding.DestinationType.QUEUE, "exchange.fanout", "learn.msg",null));

        rabbitAdmin.declareBinding(new Binding("fall", Binding.DestinationType.QUEUE, "exchange.topic", "fall",null));
        rabbitAdmin.declareBinding(new Binding("fall.other", Binding.DestinationType.QUEUE, "exchange.topic", "fall.#",null));
        rabbitAdmin.declareBinding(new Binding("fall.msg", Binding.DestinationType.QUEUE, "exchange.topic", "fall.#",null));
        rabbitAdmin.declareBinding(new Binding("fall.msg", Binding.DestinationType.QUEUE, "exchange.topic", "*.msg",null));
        rabbitAdmin.declareBinding(new Binding("learn.msg", Binding.DestinationType.QUEUE, "exchange.topic", "*.msg",null));

    }

    /**
     * 测试使用RabbitTemplate发送简单数据(如字符串)
     */
    @Test
    public void testRabbitTemplate() {
        // 向RabbitMQ发送消息的几种方法:
        // 1、直接使用send方法,需要自己构造Message
        //rabbitTemplate.send(exchange,routingKey,message);

        // 2、 使用convertAndSend,只要传入要发送的对象,会自动序列化后发送给mq
        rabbitTemplate.convertAndSend("exchange.direct", "fall", "hello fall~");
    }

    /**
     * 测试发送对象数据
     *  前提要求:要发送的对象的类实现了序列化接口
     *  public void convertAndSend(String exchange, String routingKey, Object object)
     *      exchange    :发送目标交换器的名字
     *      routingKey  :消息的路由键
     *      object      :发送的消息内容
     */
    @Test
    public void testRabbit02() {
        rabbitTemplate.convertAndSend("exchange.topic", "fall.xx",new Person(1,"lis"));
        System.out.println("finish");
    }

    /**
     * 从指定的队列中获得队列中的消息
     */
    @Test
    public void testRabbit03() {
        Object o = rabbitTemplate.receiveAndConvert("fall.msg");    // 传入队列的名字
        System.out.println("class: " + o.getClass());
        System.out.println("toString: " + o);
    }
}
使用自定义MessageConverter
@Configuration
public class MyRabbitMQConfig {

    // 配置自定义的MessageConverter,代替默认的,以达到自动将对象在放入消息队列时转换成JSON格式的目的
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }
}

只要将自定义的MessageConverter加入IOC容器后,默认的就会失效,转而使用自定义的,达到在放入消息队列的时候对象呈现JSON格式的目的。

@RabbitListener简单使用

使用RabbitListener必须先在主力启动类上开启Rabbit功能(@EnableRabbit):

@SpringBootApplication
@EnableRabbit       // 开启RabbitMQ消息队列功能
public class SpringbootAmqpApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootAmqpApplication.class, args);
    }
}

在业务代码中通过@RabbitListener注解,可以实现在对应消息队列中传入数据的时候,触发标注了的方法。

并且在该方法触发的同时,队列中的消息也会被取出,而不是继续存放在队列中。

@Service
public class MyService {

    // RabbitListener注解在方法上,可以监听队列,当该队列有消息进入的时候,会触发该方法
    @RabbitListener(queues = "fall.msg")
    public void listener() {
        System.out.println("fall.msg 有新消息进入...");
    }

    // 在方法的入参加Message对象,Spring会在监听到的同时自动注入message对象,在方法中可以查看message的信息
    @RabbitListener(queues = "fall.other")
    public void listenerMessage(Message message) {
        MessageProperties messageProperties = message.getMessageProperties();
        System.out.println(messageProperties);
        // 通过getBody()方法获得byte数组格式的消息,通过new String(Byte[] bytes)获得JSON格式的对象。
        byte[] bytes = message.getBody();
        System.out.println(new String(bytes));
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
整合 RabbitMQ 可以让你的 Spring Boot 项目具备更好的异步处理和消息传递能力。下面是整合的步骤: 1. 添加 RabbitMQ 依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 2. 配置 RabbitMQ 在 application.properties 文件中添加以下配置: ``` spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ``` 如果你使用的是 RabbitMQ 的默认端口和默认用户,那么可以不用配置端口和用户名密码。 3. 创建消息接收者 ```java @Component public class Receiver { @RabbitListener(queues = "myQueue") public void processMessage(String content) { System.out.println("Received message: " + content); } } ``` 这里使用了 `@RabbitListener` 注解来监听名为 `myQueue` 的队列,并在接收到消息时打印出消息内容。 4. 创建消息发送者 ```java @Component public class Sender { @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("myQueue", message); } } ``` 这里使用了 `RabbitTemplate` 类来发送消息到名为 `myQueue` 的队列。 5. 测试 ```java @SpringBootTest class RabbitmqApplicationTests { @Autowired private Sender sender; @Test void testSendMessage() { sender.sendMessage("Hello, RabbitMQ!"); } } ``` 在测试方法中调用 `Sender` 的 `sendMessage` 方法发送消息。当消息被发送时,`Receiver` 中的 `processMessage` 方法会被自动调用,从而处理消息。 以上就是整合 RabbitMQ 的基本步骤,你可以根据自己的需求进行配置和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值