RabbitMQ入门篇【图文并茂,超级详细】

🥳🥳Welcome 的Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于Docker的相关操作吧

目录

🥳🥳Welcome 的Huihui's Code World ! !🥳🥳

前言

1.什么是MQ

2.理解MQ

3.生活案例分析与理解

4.MQ的使用场景

(1)解耦

传统模式

中间件模式

(2)削峰

传统模式

中间件模式

(3)异步

 传统模式

中间件模式

5.常见的MQ

一. RabbitMQ是什么

 二. Docker安装部署RabbitMQ

 1.拉取镜像

2.安装

3.访问

三.springboot连接配置

1.进入rabbitmq管理界面

2.创建用户

3.分配权限给用户

四.代码实现简单队列 

1.创建一个生产者模块

2.创建一个消费者模块

3.代码操作

(1)配置RabbitMQ消息队列

(2)向消息队列发消息

(3)连接rabbitmq测试

(4)RabbitMQ消息队列的消费者

(5)成自定义数据发送

①配置RabbitMQ消息队列

②RabbitMQ消息队列的消费者

五.本篇问题总结

1.端口没开

2.配置文件的层级关系

3.配置文件中的信息核对


前言

        其实在讲解RabbitMQ之前,我们应该先明白为什么要使用RabbitMQ,RabbitMQ能给我们带来什么效益...

       在公司中做项目时,当项目已经迭代了几个版本了,代码量已经很大了,此时我们需要再增加一个业务功能那么这就需要提供新增一个业务接口,但如果这个时候再去更改原来的代码就会很困难,需要修改很多的地方。。。

        其实这个时候我们就可以使用到消息队列去优化项目,这样就算我们后来有新的功能需要添加,也不用跟上面一样修改很多的代码。

1.什么是MQ

Message queue相当于一个中间件,用于生产方通过MQ与消费方之间的交互作用

服务之间最常见的通信方式是直接调用彼此来通信,消息从一端发出后立即就可以达到另一端,称为即时消息通讯(同步通信)

也就是两人面对面交流,必须同步进行,除此之外不做任何事情,就像打电话一样的

消息从某一端发出后,首先进入一个容器进行临时存储,当达到某种条件后,再由这个容器发送给另一端,称为延迟消息通讯(异步通信)

相当于通过第三方转述对话,可能有消息的延迟,但不需要二人时刻保持联系,消息传给第三方后,两人可以做其他自己想做的事情,当需要获取对方说话的内容时,直接从消息队列里获取即可。就像发微信一样

2.理解MQ

  • 消息:就是两台计算机间传送的数据单位;本质上就是一段数据,它能被一个或者多个应用程序所理解,是应用程序之间传递的信息载体。消息可以非常简单,例如只包含文本字符串;也可以更复杂地嵌入对象。
  • 队列:是数据结构中概念。在队列中,数据先进先出,后进后出,犹如排队做核酸。
  • 消息队列:MQ是把消息和队列结合起来,称之为消息队列(Message Queue)。把要传输的数据(消息)与队列进行绑定,用队列先进先出机制来实现消息传递。消息队列由 生产者 和 消费者 两部分构成;生产者主要负责产生消息并把消息放入队列中,再由消费者去处理。消费者可以到指定队列中获取消息,或者订阅相应的队列,最后由MQ服务端进行消息推送。

3.生活案例分析与理解

看书案例

小红希望小明多读书,常寻找好书给小明看,之前的方式是这样:小红问小明什么时候有空,把书给小明送去,并亲眼监督小明读完书才走.久而久之,两人都觉得麻烦. 后来的方式改成了:小红对小明说「我放到书架上的书你都要看」,然后小红每次发现不错的书都放到书架上,小明则看到书架上有书就拿下来看.【书架就是一个消息队列,小红是生产者,小明是消费者.】

案例分析

改变方式之后带来的好处

  • 1. 小红想给小明书的时候,不必问小明什么时候有空,亲手把书交给他了,小红只把书放到书架上就行了.这样小红小明的时间都更自由.
  • 2. 小红相信小明的读书自觉和读书能力,不必亲眼观察小明的读书过程,小红只要做一个放书的动作,很节省时间.
  • 3. 当明天有另一个爱读书的小伙伴小强加入,小红仍旧只需要把书放到书架上,小明和小强从书架上取书即可
  • 4. 书架上的书放在那里,小明阅读速度快就早点看完,阅读速度慢就晚点看完,没关系,比起小红把书递给小明并监督小明读完的方式,小明的压力会小一些

消息队列特点

  • 1. 解耦:每个成员不必受其他成员影响,可以更独立自主,只通过一个简单的容器来联系.
  • 2. 提速:小红选只要做一个放书的动作,为自己节省了大量时间.
  • 3. 广播:小红只需要劳动一次,就可以让多个小伙伴有书可读,这大大地节省了她的时间,也让新的小伙伴的加入成本很低.
  • 4. 错峰与流控:小红给书的频率不稳定,如果今明两天连给了五本,之后隔三个月才又给一本,那小明只要在三个月内从书架上陆续取走五本书读完就行了,压力就不那么大了.

也可以用生活中做核酸的例子来理解一下

4.MQ的使用场景

上面也已经用生活案例说明的MQ的使用的好处(场景),这里再来罗列以及分析对比一下...

(1)解耦

传统模式

系统间耦合性太强,如图所示,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统A还需要修改代码,过于麻烦!

中间件模式

将消息写入消息队列,需要消息的系统自己从消息队列中订阅,从而系统A不需要做任何修改。

(2)削峰

传统模式

并发量大的时候,所有的请求直接怼到数据库,造成数据库连接异常

中间件模式

系统A慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息

(3)异步

 传统模式

一些非必要的业务逻辑以同步的方式运行,太耗费时间

中间件模式

 将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度

5.常见的MQ

消息队列有很多,这里我们使用的是RabbitMQ,也可以选择使用其他的MQ...

那么接下来我就来讲述一下RabbitMQ的相关点

一. RabbitMQ是什么

        RabbitMQ是一种开源的消息队列软件,它实现了高级消息队列协议(AMQP)标准。它可以在分布式系统中作为消息传递的中间层来处理异步通信和解耦。通过将生产者和消费者解耦,RabbitMQ可以提高系统的可靠性、扩展性和可维护性。它还支持多种编程语言和平台,并且具有许多高级功能,例如消息确认、消息持久化、消息路由和负载均衡等。RabbitMQ在企业应用程序、大数据、云计算、物联网等领域都得到广泛应用

  • Server(Broker):接收客户端连接,实现AMQP协议的消息队列和路由功能的进程.
  • Virtual Host:虚拟主机的概念,类似权限控制组,一个Virtual Host里可以有多个Exchange和Queue.
  • Exchange:交换机,接收生产者发送的消息,并根据Routing Key将消息路由到服务器中的队列Queue.
  • ExchangeType:交换机类型决定了路由消息行为,RabbitMQ中有三种类型Exchange,分别是fanout、direct、topic.
  • Message Queue:消息队列,用于存储还未被消费者消费的消息.
  • Message:由Header和body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、优先级是多少、由哪个Message Queue接收等.body是真正需要发送的数据内容.
  • BindingKey:绑定关键字,将一个特定的Exchange和一个特定的Queue绑定起来.

 二. Docker安装部署RabbitMQ

 1.拉取镜像

注意获取镜像的时候要获取management版本的,不要获取last版本的,management版本的才带有管理界面

docker pull rabbitmq:management

2.安装

docker run -d \
--name my-rabbitmq \
-p 5672:5672 -p 15672:15672 \
-v /home/rabbitmq:/var/lib/rabbitmq \
--hostname my-rabbitmq-host \
-e RABBITMQ_DEFAULT_VHOST=my_vhost \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
--restart=always \
rabbitmq:management
  • -d:表示以后台(守护进程)模式运行容器。
  • --name my-rabbitmq:指定容器的名称为my-rabbitmq。
  • -p 5672:5672 -p 15672:15672:将主机的5672和15672端口映射到容器内对应的端口,其中5672是RabbitMQ的消息传递端口,15672是RabbitMQ的管理界面端口。
  • -v /home/rabbitmq:/var/lib/rabbitmq:将主机上的/home/rabbitmq目录挂载到容器内的/var/lib/rabbitmq目录,用于持久化存储RabbitMQ的数据。
  • --hostname my-rabbitmq-host:设置容器的主机名为my-rabbitmq-host。
  • -e RABBITMQ_DEFAULT_VHOST=my_vhost:设置RabbitMQ的默认虚拟主机为my_vhost。
  • -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin:设置默认用户名和密码为admin/admin。
  • --restart=always:设置容器在启动时自动重启。
  • rabbitmq:management:使用rabbitmq:management镜像来运行容器,该镜像包含了RabbitMQ及其管理插件

3.访问

然后就是访问了,但是在访问之前需要设置一下防火墙的相关配置...

防火墙设置好之后,开启那个rabbitmq的容器就好啦

现在就可以访问了

三.springboot连接配置

1.进入rabbitmq管理界面

然后输入密码之后就可以进入到里面啦

如果分不清页面上的东西,那么可以把这个页面翻译成中文的

2.创建用户

3.分配权限给用户

然后再退出登录,使用wh的这个账号登录一下

四.代码实现简单队列 

1.创建一个生产者模块

它的父项目是一个空项目,下面是这个生产者模块选择的依赖

server:
  port: 8888
spring:
    rabbitmq:
        host: 192.168.101.129
        username: wh
        password: 123456
        port: 5672
        virtual-host: my_vhost
        connection-timeout: 0

2.创建一个消费者模块

其中用到的依赖跟上面是一样的

server:
  port: 9999
spring:
  rabbitmq:
    host: 192.168.101.129
    password: 123456
    port: 5672
    username: wh
    virtual-host: my_vhost

3.代码操作

(1)配置RabbitMQ消息队列

package com.example.publisher;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 使用@Configuration注解标记这是一个配置类
@Configuration
// 忽略所有警告
@SuppressWarnings("all")
public class RabbitConfig {
    // 定义一个名为firstQueue的方法,返回类型为Queue
    @Bean
    public Queue firstQueue() {
        // 创建一个新的Queue对象,名称为"firstQueue"
        return new Queue("firstQueue");
    }
}

(2)向消息队列发消息

package com.example.publisher;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author是辉辉啦
 * @create 2024-01-19-19:25
 */
@RestController
public class TestController {
    @Autowired
    private AmqpTemplate amqpTemplate;
   @RequestMapping("/send01")
    public String send01(){
       //像消息队列发送消息
       amqpTemplate.convertAndSend("firstQueue", "Hello World");
       return "😙😙";
   }
    @RequestMapping("/hh")
    public String hh(){
        //像消息队列发送消息
        return "😙😙";
    }
}

(3)连接rabbitmq测试

这时候就可以看到连接成功了

里面也多了一个新的队列

(4)RabbitMQ消息队列的消费者

package com.example.consumer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

// 定义一个名为Receiver的组件类,用于处理接收到的消息
@Component
// 抑制所有警告信息
@SuppressWarnings("all")
// 使用SLF4J日志框架进行日志记录
@Slf4j
// 监听名为"firstQueue"的队列
@RabbitListener(queues = "firstQueue")
public class Receiver {
    // 使用@RabbitHandler注解标记处理方法,该方法会在接收到消息时被调用
    @RabbitHandler
    public void process(String msg) {
        // 记录接收到的消息内容
        log.warn("接收到:" + msg);
    }
}

其中可以接收到生产者的消息

(5)成自定义数据发送

这个user对象生产者模块和消费者模块都要放置...如果觉得麻烦可以建一个公共项目放置dto

package com.example.publisher;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;

@SuppressWarnings("all")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String username;
private String userpwd;
}
①配置RabbitMQ消息队列
package com.example.publisher;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 使用@Configuration注解标记这是一个配置类
@Configuration
// 忽略所有警告
@SuppressWarnings("all")
public class RabbitConfig {
    // 定义一个名为firstQueue的方法,返回类型为Queue
    @Bean
    public Queue firstQueue() {
        // 创建一个新的Queue对象,名称为"firstQueue"
        return new Queue("firstQueue");
    }

    // 定义一个名为secondQueue的方法,返回类型为Queue
    @Bean
    public Queue secondQueue() {
        // 创建一个新的Queue对象,名称为"secondQueue"
        return new Queue("secondQueue");
    }
}
②RabbitMQ消息队列的消费者
package com.example.consumer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

// 定义一个名为Receiver的组件类,用于处理接收到的消息
@Component
// 抑制所有警告信息
@SuppressWarnings("all")
// 使用SLF4J日志框架进行日志记录
@Slf4j
// 监听名为"firstQueue"的队列
@RabbitListener(queues = "secondQueue")
public class ModelReceiver {
    // 使用@RabbitHandler注解标记处理方法,该方法会在接收到消息时被调用
    @RabbitHandler
    public void process(User user) {
        // 记录接收到的消息内容
        log.warn("接收到:" + user);
    }
}

成功

五.本篇问题总结

1.端口没开

在使用spring连接rabbitmq时,发现一直处于连接超时/拒绝连接的状态,后来发现是防火墙的端口没有开

启动防火墙

systemctl start firewalld

开放端口

firewall-cmd --zone=public --add-port=端口号/tcp --permanent

刷新防火墙规则

firewall-cmd --reload

查看防火墙列表

firewall-cmd --zone=public --list-ports

项目的端口以及rabbitmq的端口都需要开启

2.配置文件的层级关系

但是后面发现还是有问题,结果是配置文件的格式问题,这个rabbitmq是放在spring下面,一i的那个不要放错

3.配置文件中的信息核对

  • server.port:指定了应用程序的HTTP端口号,这里设置为9999;
  • spring.rabbitmq.host:指定了RabbitMQ服务器的IP地址或主机名,这里设置为192.168.101.129;
  • spring.rabbitmq.usernamespring.rabbitmq.password:分别指定了连接RabbitMQ所使用的用户名和密码,这里设置为wh和123456;
  • spring.rabbitmq.port:指定了RabbitMQ服务的端口号,这里设置为5672;
  • spring.rabbitmq.virtual-host:指定了RabbitMQ的虚拟主机,以便在多个应用程序之间区分不同的队列和交换机,这里设置为my_vhost。

还有就是要检查好自己的用户名与密码是否是对的,还有就是RabbitMQ服务器的IP地址或主机名一定要写对【自己的RabbitMQ安装在哪里就填写哪个的地址】,以及配置文件里面的东西都需要核对清楚

好啦,今天的分享就到这了,希望能够帮到你呢!😊😊 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/335113.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

去掉element-ui的el-table的所有边框+表头+背景颜色

实例: 1.去掉table表头(加上:show-header"false") <el-table:data"tableData":show-header"false"style"width: 100%"> </el-table> 2.去掉table所有边框 ::v-deep .el-table--border th.el-table__cell, ::v-deep .el…

Git教程学习:05 撤销操作

文章目录 1 撤销操作2 取消暂存的文件3 撤销对文件的修改 1 撤销操作 这里&#xff0c;我们将会学习几个撤销基本工具。 注意&#xff0c;有些撤销操作是不可逆的。 这是在使用 Git 的过程中&#xff0c;会因为操作失误而导致之前的工作丢失的少有的几个地方之一。 有时候我们…

win系统环境搭建(十五)——如何将Windows系统备份

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十五&#xff09;——如何将Windows系统备份 文章目录 win系统环境搭建&#xff08;十五&#xff09;——如何将Windows系统备份1.为什么要做备份&#xff1f;1.1 关于启动快速启动1.2 关于BitLocker1.3…

【0到1的设计之路】从C语言到二进制程序

C程序如何从源代码生成指令序列(二进制可执行文件) 预处理 -> 编译 -> 汇编 -> 链接 -> 执行 预处理 预处理 文本粘贴 #include <stdio.h> #define MSG "Hello \ World!\n" int main() {printf(MSG /* "hi!\n" */); #ifdef __riscvpr…

2.C语言——控制语句

控制语句 1.分支语句/判断语句if 语句if...else 语句if...else if...else语句 switch语句 2.循环语句 while 语句 do...while 语句 for 语句 3.转向语句 break continue go to 1.分支语句/判断语句 if 语句 if(boolean_expression) { /* 如果布尔表达式为真将执行的语句 */ } …

【已解决】namespace “Ui“没有成员 xxx

先说笔者遇到的问题&#xff0c;我创建一个QWidget ui文件&#xff0c;然后编辑的七七八八后&#xff0c;想要用.h与.cpp调用其&#xff0c;编译通过&#xff0c;结果报了这个错误&#xff0c;本方法不是普适性&#xff0c;但是确实解决了这个鸟问题。 问题来源 搭建ui后&…

【算法与数据结构】1049、LeetCode 最后一块石头的重量 II

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题需要得到石头之间两两粉碎之后的最小值&#xff0c;那么一个简单的思路就是将这堆石头划分成大小相…

python使用jupyter记笔记

目录 一、安装 二、运行jupyter 三、使用 四、记笔记 Jupyter Notebook&#xff08;此前被称为 IPython notebook&#xff09;是一个交互式笔记本&#xff0c;支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序&#xff0c;便于创建和共享程序文档&a…

ChatGPT与文心一言:AI助手之巅的对决

随着科技的飞速发展&#xff0c;人工智能助手已经渗透到我们的日常生活和工作中。 而在这个充满竞争的领域里&#xff0c;ChatGPT和文心一言无疑是最引人注目的两款产品。它们各自拥有独特的优势&#xff0c;但在智能回复、语言准确性、知识库丰富度等方面却存在差异。那么&am…

unity-声音与声效OLD

声音与声效 基本概念audio clipaudio listeneraudio source 基本操作如何创建音频源&#xff08;背景音乐&#xff09;如何在测试的时候关闭声音 常用代码一般流程如何在一个物体上播放多个音效如何在代码中延时播放多个声音如何在代码中停止音频的播放如何判断当前是否在播放音…

Linux 【C编程】 引入线程,线程相关函数

1.线程的引入 1.1使用线程同时读取键盘和鼠标 代码演示&#xff1a; #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <termios.h> #include <fcntl.h> #include <string.h> // 读取…

可媲美Gen2的视频生成大一统模型;Vlogger根据用户描述生成分钟级视频;Vision Mamba提速2.8倍节省86.8%

本文首发于公众号&#xff1a;机器感知 可媲美Gen2的视频生成大一统模型&#xff1b;Vlogger根据用户描述生成分钟级视频&#xff1b;Vision Mamba提速2.8倍节省86.8% UniVG: Towards UNIfied-modal Video Generation Current efforts are mainly concentrated on single-obj…

00-Rust前言

问&#xff1a;为什么要近期想学习Rust? 答&#xff1a; Rust出来也是有一段时间了&#xff0c;从Microsoft吵着要重构他们的C"祖传代码"开始&#xff0c;Rust就披着“高效&#xff0c;安全”的头衔。而自己决定要学习Rust&#xff0c;是因为近期发现&#xff1a;与…

redisson的延时队列机制简述

概述 业务中经常会遇到一些延迟执行的需求&#xff1b;通常想到的都是rabbitmq或者rocketmq的延迟消息&#xff1b; 但是系统中不一定集成了mq&#xff0c;但为了控制分布式下的并发&#xff0c;一般redis都是有集成的&#xff1b; redis的key过期监听那个时间不准确&#xff…

C#,实用新型加强版的整数数组

疫苗要打加强针&#xff01;数组要用加强版&#xff01; 三连发 加强版整数数组源代码https://mp.csdn.net/mp_blog/creation/editor/124151056 加强版实数数组源代码https://mp.csdn.net/mp_blog/creation/editor/124151110 加强版泛型数组源代码https://mp.csdn.net/mp_bl…

这才是你应该了解的Redis数据结构!

Redis&#xff0c;作为一种高性能的内存数据库&#xff0c;支持多种数据结构&#xff0c;从简单的字符串到复杂的哈希表。在这篇博文中&#xff0c;我们将深入探讨Redis的一些主要数据结构&#xff0c;并通过详细的例子展示它们的使用。 1. 字符串 (String) 1.1 存储和获取 R…

k8s资源介绍

Kubernetes架构图 Kubernetes系统用于管理分布式节点集群中的微服务或容器化应用程序&#xff0c;并且其提供了零停机时间部署、自动回滚、缩放和容器的自愈&#xff08;其中包括自动配置、自动重启、自动复制的高弹性基础设施&#xff0c;以及容器的自动缩放等&#xff09;等…

模糊数学在处理激光雷达的不确定性和模糊性问题中的应用

模糊数学是一种用于处理不确定性和模糊性问题的数学工具&#xff0c;它可以帮助我们更好地处理激光雷达数据中的不确定性和模糊性。激光雷达是一种常用的传感器&#xff0c;用于测量目标物体的距离、速度和方向等信息。然而&#xff0c;在实际应用中&#xff0c;激光雷达所获取…

ITK + ANT,无法显示三维

背景&#xff1a;之前用ANT保存ima格式的数据&#xff0c;选择的是保存所有的序列 用python将dicom转为nii的格式&#xff0c; import nibabel as nib import torch"""不管是nii还是nii.gz都是二维的&#xff0c;为啥呢"""fobj nib.load("…

Linux编辑器---vim

目录 1、vim的基本概念 2正常/普通/命令模式(Normal mode) 2、1命令模式下一些命令&#xff08;不用进入插入模式&#xff09; 3插入模式(Insert mode) 4末行/底行模式(last line mode) 4、1底行模式下的一些命令 5、普通用户无法进行sudo提权的解决方案 6、vim配置问题 6、1配…