springboot整合rabbitmq

目录

 一、rabbitmq的相关概念

概念说明:

 二、相关步骤(整合springbbot)

 三、具体实现和对应的原理

1、配置rabbitmq的文件

2、配置configuration文件,配置连接

3、创建exchange

4、创建队列

5、绑定队列和exchange

6、创建生产者

7、创建消费者

8、完成消费

四、延迟队列和死信队列


一、rabbitmq的相关概念

RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是 AMQP(高级消息队列协议)的标准实现。

概念说明:

Broker:简单来说就是消息队列服务器实体。
Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
producer:消息生产者,就是投递消息的程序。
consumer:消息消费者,就是接受消息的程序。
channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。
原文链接https://blog.csdn.net/qq_26597927/article/details/95353748icon-default.png?t=L9C2https://blog.csdn.net/qq_26597927/article/details/95353748

 二、相关步骤(整合springbbot)

1、配置rabbitmq的文件

2、配置configuration文件,配置连接

3、创建exchange

4、创建队列

5、绑定队列和exchange

6、创建生产者

7、创建消费者

8、完成消费

三、具体实现和对应的原理

以下rabbitmq简称为mq


1、配置rabbitmq的文件

首先我们得知道mq的端口是5672,不是15672,15672的是web的可视化的mq。就是它

接下来就是配置文件的设置

一般是这样的

spring:

  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    virtual-host: /

host 为地址,port为端口。username为用户名,password为密码(guest为其默认的初始账号和密码),virtual-host 为虚拟地址(类似为不同的数据库,其中的exchange和queue互不干扰)

如何新增virtual-host

 这样你本地mq中就会有这个lib_sys,如果你不去新增直接去连接会连接失败的。


 2、配置configuration文件,配置连接

接下来就是配置configuration文件。

@Configuration
public class RabbitmqConfig {

    private final RabbitProperties rabbitProperties;

    public RabbitmqConfig(RabbitProperties rabbitProperties) {
        this.rabbitProperties = rabbitProperties;
    }

    @Bean
    public ConnectionFactory getConnectionFactory() {
        com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory =
                new com.rabbitmq.client.ConnectionFactory();
        //用户连接的地址
        rabbitConnectionFactory.setHost(rabbitProperties.getHost());
        //端口号
        rabbitConnectionFactory.setPort(rabbitProperties.getPort());
        //虚拟主机
        rabbitConnectionFactory.setVirtualHost(rabbitProperties.getVirtualHost());
        //用户名
        rabbitConnectionFactory.setUsername(rabbitProperties.getUsername());
        //密码
        rabbitConnectionFactory.setPassword(rabbitProperties.getPassword());
        //自动连接恢复
        rabbitConnectionFactory.setAutomaticRecoveryEnabled(true);
        //设置连接恢复间隔时间默认为500
        rabbitConnectionFactory.setNetworkRecoveryInterval(5000);
        return new CachingConnectionFactory(rabbitConnectionFactory);
    }



}

首先创建一个连接工厂,这个工厂要取得我们之前配置的yml文件的配置信息。

如果你的不是本地的,而是对应买的阿里云的mq的话,就是下面的

    public ConnectionFactory getConnectionFactory() {
        com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory =
                new com.rabbitmq.client.ConnectionFactory();
        rabbitConnectionFactory.setHost(rabbitProperties.getHost());
        rabbitConnectionFactory.setPort(rabbitProperties.getPort());
        rabbitConnectionFactory.setVirtualHost(rabbitProperties.getVirtualHost());
        AliyunCredentialsProvider credentialsProvider = new AliyunCredentialsProvider(
                rabbitProperties.getUsername(), rabbitProperties.getPassword(), INSTANCE_ID);
        rabbitConnectionFactory.setCredentialsProvider(credentialsProvider);
        rabbitConnectionFactory.setAutomaticRecoveryEnabled(true);
        rabbitConnectionFactory.setNetworkRecoveryInterval(5000);
        return new CachingConnectionFactory(rabbitConnectionFactory);
    }

其中 INSTANCE_ID 为你买了mq后阿里云给你的。


3、创建exchange

exchange不存储东西,只是一个交换机,对信息进行交换,一般分为四种,分别是:
DirectExchange :根据对应的路由进行找对应的queue

FanoutExchange:没有路由,找任意的queue

TopicExchange:根据路由进行模糊查找queue

HeaderExchange (基本不用)

借鉴图片分别对应上面写的exchange种类


原文链接https://blog.csdn.net/dandanzmc/article/details/52262850icon-default.png?t=L9C2https://blog.csdn.net/dandanzmc/article/details/52262850

其中exchange有一下的性质,可以直接去源码进行查看。

// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。

如果durable是true那么他会存储到本地磁盘一般是 在c盘的 文件里面,但是里面存的文件你也看不了,只要存在磁盘,如果遇到服务器重启或者断电,其内容如果还没被消费,就会一直在。(除非你设置了ttl,成为dlx死信,但是死信在一定程度上也可以找到。。。。)

%APPDATA% usually expands to C:\Users\%USERNAME%\AppData\Roaming or similar.

下面以DirectExchange为例

    /**
     * 构建exchange,并对其进行命名
     */
    @Bean
    public DirectExchange directExchange() {
        return ExchangeBuilder
                .directExchange(QueueEnum.REGISTER_QUEUE.getExchangeName())
                .durable(true)
                .build();
    }

其中direrctExchange为ExchangeVBuilder的构造方法,这里就是设置对应的路由,也可以理解设置需要连接的queue的名字。

其余属性不设置默认就采用false。


4、创建队列

创建好了exchange就可以设置对应的queue了。

当然queue也有对应的属性

原文链接https://blog.csdn.net/A232222/article/details/112340729icon-default.png?t=L9C2https://blog.csdn.net/A232222/article/details/112340729

Name:队列的名称
Durable:是否持久化(重启rabbitmq之后,队列是否还存在)
Exclusive:是否只被一个客户端连接使用,且当连接关闭后,删除队列
AutoDelete :是否自动删除(当最后一个消费者退订后即被删除)
Arguments:队列的其他属性参数,有如下可选项:
(1)x-message-ttl:消息的过期时间,单位:毫秒;
(2)x-expires:队列过期时间,队列在多长时间未被访问将被删除,单位:毫秒;
(3)x-max-length:队列最大长度,超过该最大值,则将从队列头部开始删除消息;
(4)x-max-length-bytes:队列消息内容占用最大空间,受限于内存大小,超过该阈值则从队列头部开始删除消息;
(5)x-overflow:设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head;
(6)x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中;
(7)x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,如果不设置,则使用消息的原来的路由键值
(8)x-single-active-consumer:表示队列是否是单一活动消费者,true时,注册的消费组内只有一个消费者消费消息,其他被忽略,false时消息循环分发给所有消费者(默认false)
(9)x-max-priority:队列要支持的最大优先级数;如果未设置,队列将不支持消息优先级;
(10)x-queue-mode(Lazy mode):将队列设置为延迟模式,在磁盘上保留尽可能多的消息,以减少RAM的使用;如果未设置,队列将保留内存缓存以尽可能快地传递消息;
(11)x-queue-master-locator:在集群模式下设置镜像队列的主节点信息。

直接上代码

    /**
     * 队列
     */
    @Bean
    public Queue queue() {
        return QueueBuilder
                .durable(QueueEnum.REGISTER_QUEUE.getQueueName())
                .build();
    }

其中durable()为其queueBuilder的构造方法,里面的参数是queue的名字,需要和exchange对应,不然找不到。(当然队列有死信队列和延迟队列,这里先不考虑)


5、绑定队列和exchange

接下来就是把exchange和queue绑定起来

    /**
     * 交换机绑定队列
     * 队列绑定交换机,并存储起来
     */
    @Bean
    Binding binding() {
        return BindingBuilder
                .bind(queue())
                .to(directExchange())
                .with(QueueEnum.REGISTER_QUEUE.getPath());
    }

当然以上的2,3,4,5都是同一个configuration文件里面的,完整的代码见代码1。


6、创建生产者

主要是把信息上传到mq中,可以写一个对应的方法,每次需要使用mq的时候直接调用就好了。

package com.library.until;


import com.library.enums.QueueEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author zwh
 * 作用就是发送消息
 */
@Component
@Slf4j
public class RabbitUtils {

    private static AmqpTemplate amqpTemplate;

    @Autowired
    public void setAmqpTemplate(AmqpTemplate amqpTemplate) {
        RabbitUtils.amqpTemplate = amqpTemplate;
    }

    /**
     * 发送普通消息
     * @param msg 消息内容
     */
    public static void sendNormalMsg(String msg, QueueEnum queueEnum){
        amqpTemplate.convertAndSend(queueEnum.getExchangeName(),queueEnum.getPath(),msg);
        log.info("send msg :{}",msg);
    }

    /**
     * 发送延迟消息
     * @param msg 消息内容
     * @param delayTime 延迟时间,单位毫秒
     */
    public static void sendDelayMsg(String msg, Long delayTime,QueueEnum queueEnum){
        amqpTemplate.convertAndSend(queueEnum.getExchangeName(),queueEnum.getPath(),msg,message -> {
            message.getMessageProperties().setExpiration(delayTime.toString());
            return message;
        });
        log.info("send delay msg :{}",msg);
    }


}

这里采用的是String,也可以上传其他类型的,比如集合,json等等,这边需要自己改。

然后再业务逻辑中调用方法就好了。

我这里测试的是在注册的时候调用方法,存储信息,然后告诉发信息给用户,告诉用户成功注册。

这样生产者就好了。


7、创建消费者

创建消费者,一般都是实时监听我们的mq,然后获得信息后在做接下来的业务处理。

package com.library.rabbitmqListener;


import com.library.entity.Admin;
import com.library.service.AdminService;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author zwh
 * 及时监听,并及时消费,作为一个消费者
 */
@Component
@RabbitListener(queues = "register_queue") //对应你的队列的名称
@RequiredArgsConstructor
public class registerListener {
    private final AdminService adminService;

    @RabbitHandler
    public void handle(String msg){
        System.out.println("我接收到了mq的消息了");
        System.out.println(msg);
        Long id = Long.valueOf(msg);
        System.out.println("新建的管理员是:" + " " +adminService.getById(id).getName() );
        System.out.println("恭喜您成功注册成为一名图书馆管理系统的管理员!");

    }
}

这里把打简化为后面得到信息的业务处理。

要注意

@RabbitListener(queues = "register_queue")
@RabbitHandler

这里不能忘了,不然不会执行成功的。


8、完成消费

由于这里的消费是实时的,我先注释掉消费任务,让大家看到我们的mq是否成功的存到信息。

运行后,如果没有消费者,那么这个就不会被消费。

接下来注释去掉,运行。

 看到还没完全运行好程序,这个就开始消费了。

然后再看mq

已经被消费过了,所以里面就没有了。

四、延迟队列和死信队列

见下文分析

附录1

package com.library.config;

/**
 * @author zhuwenhai
 * @date 2021/10/27 15:46
 */

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.library.enums.QueueEnum;
import lombok.RequiredArgsConstructor;
import net.bytebuddy.dynamic.loading.ClassInjector;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Configuration
public class RabbitmqConfig {

    private final RabbitProperties rabbitProperties;

    public RabbitmqConfig(RabbitProperties rabbitProperties) {
        this.rabbitProperties = rabbitProperties;
    }

    @Bean
    public ConnectionFactory getConnectionFactory() {
        com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory =
                new com.rabbitmq.client.ConnectionFactory();
        //用户连接的地址
        rabbitConnectionFactory.setHost(rabbitProperties.getHost());
        //端口号
        rabbitConnectionFactory.setPort(rabbitProperties.getPort());
        //虚拟主机
        rabbitConnectionFactory.setVirtualHost(rabbitProperties.getVirtualHost());
        //用户名
        rabbitConnectionFactory.setUsername(rabbitProperties.getUsername());
        //密码
        rabbitConnectionFactory.setPassword(rabbitProperties.getPassword());
        //自动连接恢复
        rabbitConnectionFactory.setAutomaticRecoveryEnabled(true);
        //设置连接恢复间隔时间默认为500
        rabbitConnectionFactory.setNetworkRecoveryInterval(5000);
        return new CachingConnectionFactory(rabbitConnectionFactory);
    }

    /**
     * 构建exchange,并对其进行命名
     */
    @Bean
    public DirectExchange directExchange() {
        return ExchangeBuilder
                .directExchange(QueueEnum.REGISTER_QUEUE.getExchangeName())
                .durable(true)
                .build();
    }


    /**
     * 队列
     */
    @Bean
    public Queue queue() {
        return QueueBuilder
                .durable(QueueEnum.REGISTER_QUEUE.getQueueName())
                .build();
    }

    /**
     * 交换机绑定队列
     * 队列绑定交换机,并存储起来
     */
    @Bean
    Binding binding() {
        return BindingBuilder
                .bind(queue())
                .to(directExchange())
                .with(QueueEnum.REGISTER_QUEUE.getPath());
    }


}

附录2

package com.library.enums;

import lombok.Getter;

/**
 * @author zwh
 */
@Getter
public enum QueueEnum {

    /**
     * 队列枚举
     */
    //注册队列
    REGISTER_QUEUE("register_exchange","register_queue","register_queue")
    ;

    private String exchangeName;
    private String queueName;
    private String path;

    QueueEnum(String exchangeName, String queueName, String path) {
        this.exchangeName = exchangeName;
        this.queueName = queueName;
        this.path = path;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot框架可以很容易地与RabbitMQ进行集成。为了实现这个目标,你需要在项目的依赖项中添加两个关键的依赖项。首先,你需要添加spring-boot-starter-amqp依赖项,它提供了与RabbitMQ进行通信的必要类和方法。其次,你还需要添加spring-boot-starter-web依赖项,以便在项目中使用Web功能。 在你的项目中创建两个Spring Boot应用程序,一个是RabbitMQ的生产者,另一个是消费者。通过这两个应用程序,你可以实现消息的发送和接收。生产者应用程序负责将消息发送到RabbitMQ的消息队列,而消费者应用程序则负责从队列中接收并处理消息。这样,你就可以实现基于RabbitMQ的消息传递系统。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringBoot整合RabbitMQ](https://blog.csdn.net/K_kzj_K/article/details/106642250)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Springboot 整合RabbitMq ,用心看完这一篇就够了](https://blog.csdn.net/qq_35387940/article/details/100514134)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [undefined](undefined)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值