当前位置: 首页 > 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…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...