2.6 Spring boot 整合 RabbitMQ

Spring Boot整合RabbitMQ详细教程 1.首先我们简单了解一下消息中间件的应用场景 异步处理 场景说明:用户注册后,需要发注册邮件和注册短信,传统的做法有两种1.串行的方式;2.并行的方式 (1)串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才返回给客户端。 这有一个问题是,邮件,短信并不是必须的,它只是一个通知,而这种做法让客户端等待没有必要等待的东西. (2)并行方式:将注册信... 阅读详情


1.项目准备

我们在rabbitmq目录下创建rabbitmq-springboot模块,并添加下列依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>cn.study</groupId>
	<artifactId>rabbitmq-springboot</artifactId>
	<version>1.0-SNAPSHOT</version>
	<name>rabbitmq-springboot</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.amqp</groupId>
			<artifactId>spring-rabbit-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

并设置配置文件添加rabbitmq的连接配置:

spring:
  rabbitmq:
    host: 192.168.64.140
    port: 5672
    username: admin
    password: admin

我们这里只做springboot整合rabbitmq的API进行测试,所以不需要其他额外的配置;

我们将在后续演示多种工作模式,每种工作模式都将有自己的生产者类与消费者类,如果我们使用统一的启动类进行启动运行,将会扫描所有工作模式的所有包,并自动创建所有的对象实例;

这样的话会导致实例混乱,无法有效的控制每种工作模式并区分,所以我们这里选择单独创建自己工作模式的启动类,也就是说,每种工作模式都有自己的单独的启动类;

这样启动项目时,只会扫描当前包,不会扫描其他包;

2.工作模式

springboot整合rabbitmq后,rabbitmq的相关配置将变得十分简单:

2.1 简单模式

生产者向helloworld队列发送消息,消费者从helloworld队列接收消息;

2.1.1 启动类

我们在m1包下创建单独运行的启动类,在启动类中添加队列:

package cn.study.rabbitmqspringboot.m1;

import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import javax.annotation.PostConstruct;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    //配置队列使用的参数
    // RabbitAutoConfiguration 自动配置类中,
    // 会从 spring 容器自动发现这个Queue实例,使用其中的参数在服务器上创建队列
    @Bean
    public Queue hellowordQueue(){
        return new Queue("helloworld",false,false,false);
    }
 }

2.1.2 生产者

对于生产者来说,spingboot并不能为我们自动创建,所以还是需要我们自己去进行配置:

package cn.study.rabbitmqspringboot.m1;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Scanner;

@Component
public class Producer {
    @Autowired
    private AmqpTemplate t; //用来发送消息的工具对象

    //调用send方法来发送消息
    public void send(){
        while (true){
            System.out.print("请输入要发送的消息:");
            String s = new Scanner(System.in).nextLine();
            //使用convertAndSend方法转换并发送hellowrld队列中的消息
            //这里会自动将消息转换byte[],不需要手动调用方法再进行转换
            t.convertAndSend("hellowrld",s);
        }
    }
}

2.1.3 消费者

但是对于消费者来说,通过注解配置后,spingboot会自动为我们创建实例并进行消息接收:

package cn.study.rabbitmqspringboot.m1;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener( queues = "hellowrld")
public class consumer {
    @RabbitHandler
    public void receive(String msg){
        System.out.println("收到的消息为:"+msg);
    }

/**
 * 也可以直接将 @RabbitListener( queues = "hellowrld")放到方法上进行使用
 * 但是因为@RabbitListener( queues = "hellowrld")一个类中只能存在一个
 * 所以一个类中只能创建一个消费者,没有那么灵活,不能写多个消费者的代码
    @RabbitListener( queues = "hellowrld")
    public void receive(String msg){

    }*/
}

2.1.4 测试

代码完成后,我们在启动类中创建测试方法进行消息的发送以及接收的测试:因为我们需要调用send()方法进行测试,此方法是一个while的死循环方法,直接调用会导致一直在此循环中无法结束跳出;

所以我门这里使用启动一个新的线程来执行此方法,springboot的主线程并不参与,保证主线程可以执行后续的方法;

    @Autowired
    private Producer p;

    /**
     *springboot主线程执行流程:
     *自动扫描创建实例 ---> 完成自动注入 ---> @PostConstruct ---> 后续步骤
     *@PostConstruct 一般用来执行初始化操作
     */
    @PostConstruct
    public void test() {
        new Thread(() -> p.send()).start();
    }

启动启动类后,会加载producer和consumer俩个类,自动加载扫描创建生产者和消费者,在同一个应用中创建生产者和消费者对象,这里是为了模拟测试这样设计,在实际生产环境中,生产者和消费者不应该在同一个模块中,甚至不在同一台服务器中;

在这里插入图片描述

输入消息的提示可能会和其他日志混到一起,直接输入即可;

2.2 工作队列模式

2.2.1 项目改造

对于后续的其他工作模式均与简单模式一样,进行简单的配置即可,所以后续的工作模式案例我们均在简单模式的基础上进行改造,直接复制m1包到当前目录下:
在这里插入图片描述

在启动类中,我们需要重新配置队列的属性,将其设置为持久,非独占,不自动删除的队列,并重新为其命名队列名;

并将生产者与消费者中的队列名更换为我们重新创建的队列名即可;

并且在consumer中创建第二个消费者,让其已负载均衡的方式接收处理消息:

package cn.study.rabbitmqspringboot.m2;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class consumer {
    @RabbitListener( queues = "task_queue")
    public void receive1(String msg){
        System.out.println("receive1收到的消息为:"+msg);
    }

    @RabbitListener( queues = "task_queue")
    public void receive2(String msg){
        System.out.println("receive2收到的消息为:"+msg);
    }

}

然后启动项目进行测试即可:
在这里插入图片描述

2.2.2 合理分发

目前默认的分发策略是负载均衡策略,为了实现合理分发,将消息发送到空闲的消费者,需要实现手动ack和配置qos参数为1的配置;

springboot整合RabbitMQ中,默认就是ack模式,会自动发送消息回执,也就是说,我们只需要将qos参数设置为1即可实现合理分发;

qos=1是yml配置文件中的配置内容,表示其每次接收一条消息,处理完成前不接收下一条消息:

spring:
  rabbitmq:
    host: 192.168.64.140
    port: 5672
    username: admin
    password: admin
    listener:
      simple:
        prefetch: 1 #每次接收一条,处理完成前不接收下一条消息,默认为250

2.2.3 持久化

设置持久化首先要将队列设置为持久队列,然后将发送的消息添加为持久消息,此前创建新的队列时,我们已经将其设置为了持久化队列,并且当前springboot整合RabbitMQ中,默认发送的消息就是持久消息,所以当前消息就是持久化队列;

2.3 发布订阅模式

我们将m2包中的类复制到m3包中,并在启动类中去除创建队列的代码,创建交换机:

    //创建交换机:非持久,不自动删除(默认为true,false)
    @Bean
    public FanoutExchange logs(){
        return new FanoutExchange("logs",false,false);
    }

修改生产中发送消息的相关代码,添加交换机,并删除指定的队列,在使用交换机的情况下,指定队列并没有什么效果,其是随机群发消息到所有队列的,所以指定队列的参数为空即可:

    public void send(){
        while (true){
            System.out.print("请输入要发送的消息:");
            String s = new Scanner(System.in).nextLine();
            //使用convertAndSend方法转换并发送hellowrld队列中的消息
            //这里会自动将消息转换byte[],不需要手动调用方法再进行转换
            t.convertAndSend("logs","",s);
        }
    }

消费者启动后,要创建随机队列并绑定到交换机,这里我们使用了多层嵌套注解用来完成相关绑定及配置设置:

package cn.study.rabbitmqspringboot.m3;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class consumer {
    @RabbitListener(
            bindings = @QueueBinding(value = @Queue,//队列,默认参数为:随机命名,非持久,独占,自动删除
                    exchange = @Exchange(name = "logs",declare = "false")//交换机,指定交换机名,并规定不创建交换机
                    ))
    public void receive1(String msg){
        System.out.println("receive1收到的消息为:"+msg);
    }

    @RabbitListener(
            bindings = @QueueBinding(value = @Queue,//队列,默认参数为:随机命名,非持久,独占,自动删除
                    exchange = @Exchange(name = "logs",declare = "false")//交换机,指定交换机名,并规定不创建交换机
            ))
    public void receive2(String msg){
        System.out.println("receive2收到的消息为:"+msg);
    }

}

修改完成后,启动项目进行测试我们观察到,此时消息已经是分发状态:
在这里插入图片描述

2.4 路由模式

路由模式还是和此前一致,生产者发送消息时,需要携带路由键,消费者队列和交换机绑定,需要设置绑定键,双方通过关键字进行匹配:
路由模式

我们将m3包中的代码复制到m4包中:
在这里插入图片描述

首先我们更改启动类中交换机的类型为DirectExchange,并为其命名为direct_logs;因为生产者发送消息要携带路由键,所以我们额外增加一行接收控制台输入信息的代码,并将其传递给convertAndSend,并更改交换机名称,这里要注意路由键与消息作为参数传入的顺序:

    public void send(){
        while (true){
            System.out.println("请输入要发送的消息:");
            String s = new Scanner(System.in).nextLine();
            System.out.println("请输入路由键:");
            String k = new Scanner(System.in).nextLine();
            //使用convertAndSend方法转换并发送hellowrld队列中的消息
            //这里会自动将消息转换byte[],不需要手动调用方法再进行转换
            t.convertAndSend("direct_logs",k,s);
        }
    }

消费者中我们除了需要更改交换机名称外,还需要额外添加一个关键词参数:
在这里插入图片描述

完成后即可启动项目进行测试了,

在这里插入图片描述

2.5 主题模式

同样的,我们将m4中的代码复制到m5包中,并修改启动类中的交换机为TopicExchange,修改交换机名为topic_logs,同时修改生产者与消费者的交换机为topic_logs,并重新设置消费者的绑定键:
在这里插入图片描述

完成后即可启动测试了:
在这里插入图片描述

RabbitMQ - Spring boot 整合 文章目录新建项目pom.xmlapplication.yml主程序简单模式创建主类生产者消费者测试类工作模式主类生产者生产者消费者ack模式设置 ack 模式手动执行确认操作抓取数量 新建项目 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4... 阅读详情

相关推荐

Spring Boot系列十三 Spring Boot集成RabbitMQ

1. 概述之前我有一系列关于RabbitMQ文章介绍了RabbitMQ的用法,本篇我们介绍如何在Spring Boot中集成RabbitMQ。本篇主要内容如下: 在Spring boot中消息的发送和接收的两种方式的demo 配置使用MessageConverter对消息序列化 2. Demo工程公共部分介绍工程名称:rabbitmq需要在我们的工程中的pom.xml引入新jar <!-- spri

不积跬步无以至千里; 不积小流无以成江海 1万+

SpringBoot2.6.0起及新版本中解决循环依赖问题

SpringBoot2.6.0起及新版本中解决循环依赖问题

yuanjinshenglife的专栏 5211

RabbitMQ - Spring boot 整合 RabbitMQ

一、RabbitMQ 1、RabbitMQ 使用场景 1.1、服务解耦 假设有这样一个场景, 服务A产生数据, 而服务B,C,D需要这些数据, 那么我们可以在A服务中直接调用B,C,D服务,把数据传递到下游服务即可 但是,随着我们的应用规模不断扩大,会有更多的服务需要A的数据,如果有几十甚至几百个下游服务,而且会不断变更,再加上还要考虑下游服务出错的情况,那么A服务中调用代码的维护会极为困难 这是由于服务之间耦合度过于紧密 再来考虑用RabbitMQ解耦的情况 A服务只需要向消息服务器发送消息,而不用考

weixin_54685622的博客 1625

重磅!Spring Boot 2.6 正式发布,一大波新特性,看完我彻底躺平了。。

点击关注公众号,Java干货及时送达Spring Boot 2.6.0 来了太猛了!Spring Boot 2.5.6 发布不到一个月,Spring Boot 又接连发布了三个版本:Spr...

Java技术栈,分享最主流的Java技术 8082

RabbitMQ 实战(二)Spring Boot 整合 RabbitMQ

这篇文章主要讲基本的整合。先把代码跑起来,再说什么高级特性。 RabbitMQ 中的一些术语 如果你打开 RabbitMQ web 控制台,你会发现其中有一个 Exhanges 不好理解。下面简单说明一下。 交换器(Exchange) 交换器就像路由器,我们先是把消息发到交换器,然后交换器再根据路由键(routingKey)把消息投递到对应的队列。(明白这个概念很重要,后面的代

皂白 7620

Spring Boot 整合RabbitMQ

在业务活动期间,由于用户请求量短时间内剧增,可能导致系统压力过大甚至崩溃。通过消息队列实现请求的缓冲。在高并发场景下,系统可以将请求放入消息队列,然后异步处理这些请求,从而平滑系统的处理负载,确保系统的稳定性。

Java 技术专栏,从入门到精通,熟悉企业级开发 11万+

Springboot2.6.x的启动流程和自动配置

Springboot2.6.x的启动流程和自动配置原理,截图较细,推荐跟着去源码走一遍。

马疯蜗的博客 2981

《BiLSTM with Multi-Polarity Orthogonal Attention for Implicit Sentiment Analysis》论文阅读笔记

文章名:《BiLSTM with Multi-Polarity Orthogonal Attention for Implicit Sentiment Analysis》 作者Jiyao Wei a,1, Jian Liaoa,1, Zhenfei Yanga, Suge Wanga,b,∗, Qiang Zhaoa 年份 2019 1 Introduction 目前文本情感分析多分析带...

weixin_39036944的博客 1624

解决springboot2.6版本以上使用默认的path_pattern路径匹配模式不兼容swagger问题

SpringBoot版本目前最新版3.4.x下个月即将发布3.5.x版本,由于springboot2.6版本以上路径匹配默认为path_pattern,而不是ant_pattern,这就与swagger产生兼容性问题,下面如何再不改源码的情况下,解决这个问题。使用BeanDefinitionRegistryPostProcessor接口替换已存在的WebMvcRequestHandlerProvider的Bean定义@Override@Override@Override。

MCN的博客 4584

python 中心线提取_二值分析 | OpenCV + skimage如何提取中心线

点击上方蓝字关注我们微信公众号:OpenCV学堂关注获取更多计算机视觉与深度学习知识问题前几天有个人问了我一个问题,问题是这样的,他有如下的一张二值图像:怎么得到白色Blob中心线,他希望的效果如下:显然OpenCV中常见的轮廓分析无法获得上面的中心红色线段,本质上这个问题是如何提取二值对象的骨架,提取骨架的方法在OpenCV的扩展模块中,另外skimage包也支持图像的骨架提取。这里就...

weixin_42204453的博客 4284

Python离线断网情况下安装numpy、pandas和matplotlib等常用第三方包

联网情况下在命令终端CMD中输入“pip install numpy”即可自动安装,pandas和matplotlib同理一样方法进行自动安装。 工作的电脑不能上外网,所以不能通过直接输入pip命令来安装。 环境:电脑上已经安装了Python(没有安装的请参考其他教程)。 Python离线断网情况下安装numpy、pandas和matplotlib等常用第三方包的步骤如下: ...

dayou7738的博客 4932

springcloudalibaba-SpringAMQP

交换机的作用是什么?接收publisher发送的消息将消息按照规则路由到与之绑定的队列不能缓存消息,路由失败,消息丢失FanoutExchange的会将消息路由到每个绑定的队列声明队列、交换机、绑定关系的Bean是什么?QueueBinding描述下Direct交换机与Fanout交换机的差异?Fanout交换机将消息路由给每一个与之绑定的队列Direct交换机根据RoutingKey判断路由给哪个队列如果多个队列具有相同的RoutingKey,则与Fanout功能类似**.**分割。...

早日成为鹏总 832

LNA设计学习心得记录----MOS管的选取

LNA设计学习心得---MOS管的选取仿真

weixin_40359668的博客 6118

Spring WebFlux整合reactor-rabbitmq

本文介绍了在Spring WebFlux中整合reactor-rabbitmq实现延时消息的收发方案。使用JDK17和Spring Boot 2.6.7,通过RabbitMQ的x-delay插件实现消息延时功能。文章包含四部分:1)运维配置队列、交换机和路由键;2)RabbitMQ配置类,包含连接工厂、发送者和接收者的Bean定义;3)消息监听器实现,采用手动确认模式并处理异常情况;4)延时消息发送方案,通过继承ExchangeSpecification实现x-delayed-message类型的交换机配置

bailaoshi666的博客 334

python操作git推送自己分支并合并主分支(持续优化该工具)

python git

qq_44707265的博客 857

用python自动复制粘贴excel表里某一列的数据到另一个表中

昨天接到人事小姐姐求助减轻复制粘贴的重复工作量,分享一下代码 半路新手上路 耶 把 2.xlsx 表里的第二列 的数据复制粘贴到 test.xlsx的第一列 python3.6.2 from openpyxl import Workbook from openpyxl import load_workbook from openpyxl.writer.excel import Exc...

weixin_33854644的博客 2万+

SpringBoot简单整合RabbitMQ

RabbitMQ是一个由Erlang语言编写的、开源的、在AMQP基础上完整的、可复用的企业消息系统。在上个项目中使用到了RabbitMQ进行消息的投递,本篇文章主要介绍下RabbitMQ在SpingBoot项目中的简单整合和在Docker中运行RabbitMQ容器的步骤。以上就是今天要讲的内容,本文仅仅简单介绍了RabbitMQ的使用,RabbitMQ还有多种队列模式,需要了解更多可以参考官方文档。

xin_7的博客 236

Far planner代码系列(2)

graph_decoder系列(2) 承接上文 我们接着来看decoder_node.cpp的代码部分 void GraphDecoder::Init() { /* initialize subscriber and publisher */ //graph_sub_ 订阅节点/robot_vgraph 其类型是visibility_graph_msg/Graph的消息 graph_sub_ = nh.subscribe("/robot_vgrap...

博客 1529

SpringBoot整合RabbitMQ消息队列基本环境搭建

RabbitMQ如何使用?

weixin_45673033的博客 561

模组 RG500Q入网问题分析

- [ ] 不同于公网,在5G专网环境中, 通常使用很多非标准的网络配置,如PLMN/APN等。因此,5G模组在专网环境下通常要做一些专门的配置才能正常入网,本文分析一例在专网环境, 5G终端无法入网问题的定位过程。 - [ ] 具体涉及到以下模组操作: 恢复出厂、SA only、锁BAND、配置MBN等

十年通信老兵的技术修炼之路——从3G到5G,从地面基站到卫星通信。 926

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

SpringBoot整合RabbitMQ

演示队列在需要延时处理的场景下非常有用,使用 RabbitMQ 来实现延时队列可以很好的利用 RabbitMQ 的特性,如:消息可靠发送、消息可靠投递、死信队列来保障消息至少被消费一次以及未被正确处理的消息不会被丢弃。另外,通过 RabbitMQ 集群的特性,可以很好的解决单点故障问题,不会因为单个节点挂掉导致延时队列不可用或者消息丢失。

z2698751935的博客 700

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

[Spring boot] Spring boot 整合RabbitMQ实现通过RabbitMQ进行项目的连接

认识了解安装RabbitMQ以及进行Spring boot 整合RabbitMQ实现通过RabbitMQ进行项目的连接的代码实操

weixin_57169969的博客 8762

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Spring整合RabbitMQ

超简单!入门级SpringBoot整合RabbitMQ,一看就会!

Mr_yu_shao的博客 3959

Spring Boot整合RabbitMQ

// 创建队列 @Bean public Queue queue() {/*** @param name 队列名字* @param durable 声明一个持久队列(该队列将在服务器重启后继续存在),则为true} // 创建交换机(Direct类型) @Bean public DirectExchange exchange() {} // 绑定队列到交换机 @Bean public Binding binding() {} }

哟,你又在偷偷写bug! 3686

Spring Boot 2.X - Spring Boot整合AMQP之RabbitMQ

文章目录Spring Boot 2.X - Spring Boot整合AMQP之RabbitMQRabbitMQ简介简介MessagePublisherExchangeQueueBindingConnectionChannelConsumerVirtual HostBroker引入依赖编写配置编写接口启用Rabbit注解消息监听消息测试 Spring Boot 2.X - Spring Boot整...

XUDC的程序人生 4337
上一篇: 2.5 订单流量削峰案例
下一篇: 3.6 分布式事务(六)Seata TCC模式-TCC模式介绍
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值