当前位置: 首页 > news >正文

Java开发 - 消息队列之RabbitMQ初体验

目录

前言

RabbitMQ

什么是RabbitMQ

RabbitMQ特点

安装启动

RabbitMQ和Kafka的消息收发区别

RabbitMQ使用案例

添加依赖

添加配置

创建RabbitMQ配置类

RabbitMQ消息的发送

RabbitMQ消息的接收

测试

结语


前言

前一篇,我们学习了Kafka的基本使用,这一篇,我们来学习RabbitMQ。他们作为消息队列本身都具有很强大的功能,博主写完后的感受是:这也只能算是初体验了。毕竟师父领进门,修行靠个人,但是博主怎么会做这种师傅呢?一定要手把手教会各位童鞋,暂时不去深入的讲解了,这一块内容,等博主研究准备好之后,会在后续的系列中对消息队列来一个进阶的教程,大家先入个门,慢慢学习,微服务的东西很多,先学会才是正道。

RabbitMQ

RabbitMQ多用于Java,和Kafka多用于大数据不同,RabbitMQ更偏向于功能,性能一般,所以在Java开发中,比较受欢迎。那么下面,我们就来了解一下RabbitMQ及其特点。

什么是RabbitMQ

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。所以在Java业务中使用很多,目前我所知道的很多都是用的此消息队列,只不过大家评价都是:功能强,性能一般。与其相反的,就是Kafka了:性能强,功能弱。

这是因为他们设计的目的不一样,RabbitMQ 在有大量消息堆积的情况下性能会下降,其优势体现在功能上。而Kafka一开始是用来处理海量日志的,所以体现出来就是性能强,功能弱。

所谓,尺有所短,寸有所长,正是这个道理。全都兼顾的几乎是不存在的。

RabbitMQ特点

本想去百科里复制出来,哈哈,结果百科写的太简单了:

  • 可伸缩性:集群服务
  • 消息持久化:从内存持久化消息到硬盘,再从硬盘加载到内存

真是想偷懒都没办法。

RabbitMQ拥有数以万计的用户,是最受欢迎的开源消息代理之一。从T-Mobile到Runtastic,RabbitMQ在全球范围内用于小型初创企业和大型企业。

RabbitMQ体量轻,易于在本地和云端部署。它支持多种消息协议。RabbitMQ可以部署在分布式和联合配置中,以满足大规模、高可用性的要求。

RabbitMQ可在许多操作系统和云环境中运行,并为大多数流行的语言提供大量的开发工具。

官网地址:RabbitMQ Tutorials — RabbitMQ

RabbitMQ的可靠性:体现在持久化、传输确认和发布确认上。

Flexible Routing:灵活路由,消息进入队列之前,通过RabbitMQ内置的Exchange来路由消息 ,针对一些复杂路由,还能将多个Exchange绑定在一起,通过插件实现自己的Exchange。

集群:这个是很多微服务软件都有的功能,比如Redis,ES等,通过此功能,可以实现高可用性的能力,在一个节点发生故障时,其他节点能快速使用。

多协议:RabbitMQ支持多种协议,具体看这里:Which protocols does RabbitMQ support? — RabbitMQ

多语言客户端:RabbitMQ 几乎支持所有常用语言,具体可查看这里:Clients Libraries and Developer Tools — RabbitMQ 

管理监控:这个我们在下面安装的时候会提到此后台页面,还会登录上去给大家看,类似于nacos的管理页面,通过此界面,可以管理和监控RabbitMQ。

插件:RabbitMQ 提供了许多插件,可多方面扩展,也可以自定义插件,详情可看这里:Plugins — RabbitMQ

以上,可通过访问此链接查看详细内容:Messaging that just works — RabbitMQ 

安装启动

这也是本篇内容最痛苦的一个地方,因为RabbitMQ是Erlang语言开发的,所以要先安装Erlang语言的运行环境,为了不去分别讲解Mac和Windows的安装方式,博主准备偷个懒,让大家也偷个懒。

首先,看到这里,足以说明是至少是一名初级Java工程师,你至少开发过一个项目,那么你一定知道Docker,所以,下面,让我们愉快的使用Docker来安装RabbitMQ吧。

在Docker中搜索RabbitMQ,下载rabbitmq:management:

 你下载上面的那个也是可以的,都没关系。

接着打开终端,在里面直接输入,记住,是直接输入,不用进任何目录:

docker run -d --hostname localhost --name rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:management

 

这个命令输入完成,你的 rabbitmq容器就已经跑起来了:

此时,为了测试rabbitmq是否启动成功,我们需要在浏览器输入:http://localhost:15672

打开后是一个登录页面:

因为没有设置登录的账户名和密码,所以我们采用默认的账户密码guest来登录,输入账户密码都为guest即可登录:

 

如果你想添加用户密码,那就来这里:

 

如果你想修改当前用户密码,你可点击此处:

 

有个Update this user,输入新密码即可: 

 

 

如果你不想使用当前用户名,那就新增一个用户,再删除原来的用户。到这里,安装启动这一环节就结束了,你说,博主是不是偷了个大懒呢? 

RabbitMQ和Kafka的消息收发区别

Kafka使用话题名称来收发信息,同一个话题,一个发,可多个收,使用起来结构简单易懂。

RabbitMQ则要略复杂些,它是通过交换机和路由key来指定要发送的消息队列,生产者发送消息时指定交换机和路由key,这样一个确定的消息队列就产生了,而消费者只需要指定这个产生的消息队列就可以接收到消息。

所以在编写代码时,RabbitMQ会比Kafka多一个配置类,确切的说,是每个业务都要有一个配置类,这个配置类坐的就是指定交换机和路由key,再由路由key指定队列的工作。

RabbitMQ使用案例

此处,我们依然采用前面的微服务项目作为基础,在stock模块来完成RabbitMQ的简单使用。

添加依赖

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

添加配置

spring:rabbitmq:host: localhostport: 5672username: guestpassword: guestvirtual-host: /

用户名和密码要用你上面管理页面添加的 有效用户名密码,不添加,默认guest。

创建RabbitMQ配置类

上面提到过,交换机,路由key,队列,这三者的指定需要在配置类中完成,具体要怎么做,我们来看看,stock模块之前写过quartz,我们就把config类建在quartz包下:

package com.codingfire.cloud.stock.quartz;import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;// SpringBoot整合RabbitMQ之后
// 这些配置信息要保存在Spring容器中,所以这些配置也要交给SpringBoot管理
@Configuration
public class RabbitMQConfig {// 声明需要使用的交换机\路由Key\队列的名称public static final String STOCK_EX="stock_ex";public static final String STOCK_ROUT="stock_rout";public static final String STOCK_QUEUE="stock_queue";// 声明交换机,需要几个声明几个,这里就一个// 方法中实例化交换机对象,确定名称,保存到Spring容器@Beanpublic DirectExchange stockDirectExchange(){return new DirectExchange(STOCK_EX);}// 声明队列,需要几个声明几个,这里就一个// 方法中实例化队列对象,确定名称,保存到Spring容器@Beanpublic Queue stockQueue(){return new Queue(STOCK_QUEUE);}// 声明路由Key(交换机和队列的关系),需要几个声明几个,这里就一个// 方法中实例化路由Key对象,确定名称,保存到Spring容器@Beanpublic Binding stockBinding(){return BindingBuilder.bind(stockQueue()).to(stockDirectExchange()).with(STOCK_ROUT);}
}

都是比较固定的模版,直接用就行。

RabbitMQ消息的发送

发送消息,我们可以在QuartzJob类中进行:

package com.codingfire.cloud.stock.quartz;import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;import java.time.LocalDateTime;public class QuartzJob implements Job {// RabbitTemplate就是amqp框架提供的发送消息的对象@Autowiredprivate RabbitTemplate rabbitTemplate;@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {//输出当前时间System.out.println("--------------"+ LocalDateTime.now() +"---------------");// 先简单的发送一串文字rabbitTemplate.convertAndSend(RabbitMQConfig.STOCK_EX,RabbitMQConfig.STOCK_ROUT,"黄河之水天上来,奔流到海不复还。");}
}

我们在讲解Quartz时只用这个类每隔10s打印出当前时间,现在我们在打印时间的同时,再用RabbitMQ发送一串文字,rabbitTemplate和使用redi很像,不同的是,这里是通过template指定发送的交换机和路由。 

RabbitMQ消息的接收

我们在quartz包下再建一个用于接收消息的类:

package com.codingfire.cloud.stock.quartz;import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;// 这个对象也是需要交由Spring容器管理的,才能实现监听Spring容器中保存的队列的效果
@Component
// 和Kafka不同的是Kafka在一个方法上声明监听器
// 而RabbitMQ是在类上声明,监听具体的队列名称
@RabbitListener(queues = {RabbitMQConfig.STOCK_QUEUE})
public class RabbitMQConsumer {// 监听了类,但是运行代码的一定是个方法// 框架要求这个类中只允许一个方法包含下面这个注解// 表示这个方法是处理消息的方法// 方法的参数就是消息的值@RabbitHandlerpublic void process(String str){System.out.println("接收到的消息为:"+str);}}

里面的方法名可以是自定义的,只要类上指定队列名称就可以接收,类中注释认真看,要记住。 

测试

做完这些,下面就是启动并测试的环节,由于此微服务模块配置了nacos和seata,所以这两个服务是要起的,接着就是RabbitMQ,上面已经教大家启动过了,保证是运行状态:然后运行stock的启动文件,在控制台查看消息发送接收的情况,由于博主还依赖了数据库,此处还需要启动mysql服务,大家根据自身情况启动服务,然后再次运行:

 

可以看到我们的消息收发是正常的,测试成功,同时能看到我们做Quartz时,减少库存的操作也在运行。这就是 RabbitMQ的基本使用。

在RabbitMQ后台,也能看到我们注册的交换机和消息队列等信息:

感兴趣的可以去看看。 

结语

又到了说再见的时候,RabbitMQ和Kafka一样博大精深,这里只是基本的使用,你只要知道,他们是用来收发消息的,且不需要关心什么时候完成,你可以认为他们是在系统不忙的时候才去做,这样可以降低服务器压力,另外还能实时监控:

是不是很方便呢?赶快到自己的项目中使用吧。 

相关文章:

Java开发 - 消息队列之RabbitMQ初体验

目录 前言 RabbitMQ 什么是RabbitMQ RabbitMQ特点 安装启动 RabbitMQ和Kafka的消息收发区别 RabbitMQ使用案例 添加依赖 添加配置 创建RabbitMQ配置类 RabbitMQ消息的发送 RabbitMQ消息的接收 测试 结语 前言 前一篇&#xff0c;我们学习了Kafka的基本使用&#…...

蓝桥杯入职项目(HTML + springBoot)

文章目录需要解决npm包安装axioshttp-servedebug开发下个阶段测试运行方式注意清理磁盘缓存问题解决HTML Web项目的结构通常是基于MVC&#xff08;Model-View-Controller&#xff09;模式设计的。下面是一般的项目结构&#xff1a;index.html&#xff1a;项目的入口文件&#x…...

【IAR工程】STM8S208RB基于ST标准库下按键检测

【IAR工程】STM8S208RB基于ST标准库下按键检测&#x1f4cd;相关篇《【IAR工程】STM8S208RB基于ST标准库下GPIO点灯示例》&#x1f388;《【IAR工程】STM8S208RB基于ST标准库下EXTI外部中断》&#x1f516;基于ST STM8S/A标准外设库:STSW-STM8069,版本号&#xff1a;2.3.1&…...

【5】深度学习之Pytorch——如何使用张量处理文本数据集(语料库数据集)

在计算机领域&#xff0c;不断崛起的两个领域&#xff0c;一个是CV一个是NLP&#xff0c;下面我们可以探索一下深度学习在NLP的应用和特点。 深度学习在自然语言处理&#xff08;NLP&#xff09;领域有广泛的应用。以下是一些主要的应用和特点&#xff1a; 语音识别&#xff1…...

《Spring系列》第5章 refresh()

前言 Spring框架中最重要的肯定是IOC容器&#xff0c;那么其如何进行初始化&#xff0c;就是通过refresh()这个方法&#xff0c;无论是单独使用Spring框架&#xff0c;还是SpringBoot&#xff0c;最终都会通过执行到这个方法&#xff0c;那么下面会介绍一下这个方法 一、IOC容…...

ThreeJS-缩放、旋转(四)

代码&#xff1a; <template> <div id"three_div"> </div> </template> <script> import * as THREE from "three"; import {OrbitControls } from three/examples/jsm/controls/OrbitControls export default { name: &quo…...

数据更新 | CnOpenData法拍房数据

法拍房数据 一、数据简介 法拍房&#xff0c;即“法院拍卖房产”&#xff0c;是被法院强制执行拍卖的房屋 。当债务人&#xff08;业主&#xff09;无力履行借款合约或无法清偿债务时&#xff0c;而被债权人经司法程序向法院申请强制执行&#xff0c;将债务人名下房屋拍卖&…...

【Spring从成神到升仙系列 五】从根上剖析 Spring 循环依赖

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、数据结构和算法、Kafka从入门到成神、Kafka从成神到升仙…...

设计模式之代理模式(C++)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 一、代理模式是什么&#xff1f; 代理模式是一种结构型的软件设计模式&#xff0c;在不改变原代码前提下&#xff0c;提供一个代理…...

c++11 标准模板(STL)(std::unordered_multimap)(三)

定义于头文件 <unordered_map> template< class Key, class T, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator< std::pair<const Key, T> > > class unordered…...

Linux进程控制-2

紧接着上篇博客出发&#xff0c;我们接着来讲述Linux中进程控制的内容。 目录 1.等待 1.1具体操作 1.等待 进程等待主要的作用在于&#xff1a;父进程创建子进程之后&#xff0c;等待子进程退出&#xff0c;获取子进程的退出码&#xff0c;释放子进程的资源&#xff0c;避…...

快速排序算法

一&#xff1a;快速排序思想 假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数&#xff08;不要被这个名词吓到了&#xff0c;就是一个用来参照的数&#xff0c;待会你就知道它用来做啥的了&#xff09;。为了方便&#xff…...

中华好诗词大学季第二季(四)

第七期 1,二十四友一朝尽&#xff0c;爱妾坠楼何足言出自许浑的《金谷园》&#xff0c;“爱妾”指的是谁 2,李白在《九月十日即事》借菊花表达自己的惋惜之情&#xff0c;请问九月十日是什么节日 A 后登高 B 菊花节 C 小重阳 3,贾宝玉在大观园里面题了“曲径通幽”&#xf…...

分布式系统容灾部署方案

本文主要以OceanBase部署来说明分布式系统容灾部署方案 分布式系统提供持续可用的服务尤为重要。 好的分布式系统根据需求提供不同等级的的高可用与容灾级别。 而在分布式系统中&#xff0c;数据库系统又是最核心最关键的系统。 我们以数据库分布式系统为主&#xff0c;考虑…...

Python 爬虫性能相关总结

这里我们通过请求网页例子来一步步理解爬虫性能 当我们有一个列表存放了一些url需要我们获取相关数据&#xff0c;我们首先想到的是循环 简单的循环串行 这一种方法相对来说是最慢的&#xff0c;因为一个一个循环&#xff0c;耗时是最长的&#xff0c;是所有的时间总和 代码…...

Baumer工业相机堡盟工业相机如何设置网口的IP地址(工业相机连接的网口设置IP地址步骤)

Baumer工业相机堡盟工业相机如何设置网口的IP地址&#xff08;工业相机连接的网口设置IP地址步骤&#xff09;Baumer工业相机Baumer工业相机设置网络端口IP地址匹配设置网络端口IP地址和工业相机IP地址匹配第一次打开CameraExplorer软件确认问题为IP地址不匹配问题打开网络连接…...

Android MediaCodec设置H264 Profile到High

H264 High Profile压缩率高&#xff0c;能降低码率&#xff0c;这里记录下MediaCodec Profile设置到High遇到的一些问题。 Android 4.1 就引入了MediaCodecInfo.CodecProfileLevel类&#xff0c;下面截取H264(AVC)的Profile和Level定义: /** Copyright (C) 2012 The Android O…...

QT之QSysInfo(查看电脑信息)

文章目录前言一、API使用总结前言 QSysInfo是Qt中用于获取有关运行应用程序的系统信息的类。 我们可以获取以下信息&#xff1a; 返回系统产品类型&#xff0c;如ios&#xff0c;windows&#xff0c;Linux等 返回当前系统的产品版本。 返回当前系统的内核类型。 返回当前系统的…...

中国塑料编织袋产业竞争状况及投资前景预测报告2023-2029年

中国塑料编织袋产业竞争状况及投资前景预测报告2023-2029年 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 《报告编号》: BG451639 《出版时间》: 2023年4月 《出版机构》: 中智正业研究院 免费售后 服务一年&#xff0c;具体内容及订购流程欢迎咨询客服人员 内容简介&…...

从头用脚分析FFmpeg源码 - av_read_frame

av_read_frame作用 /*** Return the next frame of a stream.* This function returns what is stored in the file, and does not validate* that what is there are valid frames for the decoder. It will split what is* stored in the file into frames and return one f…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...