RabbitMQ快速上手及讲解
前言:在介绍RabbitMQ之前,我们先来看下面一个场景:
1.1.1.1 异步处理
场景说明:
用户注册后,需要发注册邮件和注册短信,传统的做法有两种
1.串行的方式
(1)串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才返回给客户端。这有一个问题是,邮件,短信并不是必须的,它只是一个通知,而这种做法让客户端等待没有必要等待的东西。
(2)并行方式:将注册信息写入数据库后,发送邮件的同时,发送短信,以上三个任务完成后,返回给客户端,并行的方式能提高处理的时间。
假设三个业务节点分别使用50ms,串行方式使用时间150ms,并行使用时间100ms。虽然并性已经提高的处理时间,但是,前面说过邮件和短信对我正常的使用网站没有任何影响,客户端没有必要等着其发送完成才显示注册成功,应该是写入数据库后就返回。
(3)消息队列
引入消息队列后,把发送邮件,短信不是必须的业务逻辑异步处理。
由此可以看出,引入消息队列后,用户的响应时间就等于写入数据库的时间+写入消息队列的时间(可以忽略不计),引入消息队列后处理后,响应时间是串行的3倍,是并行的2倍。
1.1.2 应用解耦
场景:
双11是购物狂节,用户下单后,订单系统需要通知库存系统,传统的做法就是订单系统调用库存系统的接口。
这种做法有一个缺点:
- 当库存系统出现故障时,订单就会失败。
- 订单系统和库存系统高耦合。
引入消息队列
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
库存系统:订阅下单的消息,获取下单消息,进行库操作。
就算库存系统出现故障,消息队列也能保证消息的可靠投递,不会导致消息丢失。
1.1.3 流量削峰
流量削峰一般在秒杀活动中应用广泛
场景:
秒杀活动,一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。
作用:
1、可以控制活动人数,超过此一定阀值的订单直接丢弃(我为什么秒杀一次都没有成功过呢^^)
2、可以缓解短时间的高流量压垮应用(应用程序按自己的最大处理能力获取订单)
1、用户的请求,服务器收到之后,首先写入消息队列,加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面。
2、秒杀业务根据消息队列中的请求信息,再做后续处理。
常见MQ产品
ActiveMQ:基于JMS
RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好
RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会
Kafka:分布式消息系统,高吞吐量
一、RabbitMQ快速入门
RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。RabbitMQ官方地址:http://www.rabbitmq.com
二、使用步骤
1.pom.xml里导入相关的依赖:
<!--rabbitmq--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
2.application.yml配置文件:
#rabitMq配置rabbitmq:host: 120.25.228.68port: 5672virtual-host: /connection-timeout: 10000#开启Confirm机制publisher-confirm-type: correlated#开启Return机制publisher-returns: true#开启ACKlistener:type: simplesimple:#每次能接收10个消息prefetch: 10acknowledge-mode: manualdirect:acknowledge-mode: manual
3.rabbitMq交换机讲解:
1、交换机介绍:
先附加下官网文档。RabbitMQ的交换机类型共有四种,是根据其路由过程的不同而划分成的:
2、交换机模式
一、Direct Exchange(直连交换机)
直连型交换机背后的路由算法很简单——消息会传送给绑定键与消息的路由键完全匹配的那个队列。 我们用直连交换机取代了只会无脑广播的扇形交换机,并且具备了选择性接收消息的能力。
这种配置下,我们可以看到有两个队列Q1、Q2绑定到了直连交换机X上。第一个队列用的是橘色(orange)绑定键,第二个有两个绑定键,其中一个绑定键是黑色(black),另一个绑定键是绿色(green)。在此设置中,发布到交换机的带有橘色(orange)路由键的消息会被路由给队列Q1。带有黑色(black)或绿色(green)路由键的消息会被路由给Q2。其他的消息则会被丢弃。
二、 Fanout Exchange(扇型交换机)
Fanout Exchange(扇型交换机):当一个Msg发送到扇形交换机X上时,则扇形交换机X会将消息分别发送给所有绑定到X上的消息队列。扇形交换机将消息路由给绑定到自身的所有消息队列,也就是说路由键在扇形交换机里没有作用,故消息队列绑定扇形交换机时,路由键可为空。这个模式类似于广播。
三、Topic Exchange(主题交换机)
1)路由键和绑定键命名
消息路由键—发送到主题交换机的消息所携带的路由键(routing_key)不能随意命名——它必须是一个用点号分隔的词列表。当中的词可以是任何单词,不过一般都会指定一些跟消息有关的特征作为这些单词。列举几个有效的路由键的例子:“stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”。只要不超过255个字节,词的长度由你来定。
绑定键(binding key)也得使用相同的格式。主题交换机背后的逻辑跟直连交换机比较相似——一条携带特定路由键(routing key)的消息会被投送给所有绑定键(binding key)与之相匹配的队列。尽管如此,仍然有两条与绑定键相关的特殊情况:
-
(星号) 能够替代一个单词。
#(井号) 能够替代零个或多个单词。
(2)示例解析,如上图:
我们将会发送用来描述动物的多条消息。发送的消息包含带有三个单词(两个点号)的路由键(routing key)。路由键中第一个单词描述速度,第二个单词是颜色,第三个是品种: “<速度>.<颜色>.<品种>”。我们创建三个绑定:Q1通过".orange.“绑定键进行绑定,Q2使用”…rabbit" 和 “lazy.#”。
队列绑定键解释:
Q1针对所有的橘色orange动物。
Q2针对每一个有关兔子rabbits和慵懒lazy的动物的消息。
消息路由键解释:
一个带有"quick.orange.rabbit"路由键的消息会给两个队列都进行投送。消息"lazy.orange.elephant"也会投送给这两个队列。
另外一方面,“quick.orange.fox” 只会给第一个队列。"lazy.pink.rabbit"虽然与两个绑定键都匹配,但只会给第二个队列投送一遍。“quick.brown.fox” 没有匹配到任何绑定,因此会被丢弃掉。
(3)异常情况
如果我们破坏规则,发送的消息只带有一个或者四个单词,例如 “orange” 或者 "quick.orange.male.rabbit"会发生什么呢?结果是这些消息不会匹配到任何绑定,将会被丢弃。另一方面,“lazy.orange.male.rabbit”即使有四个单词,也会与最后一个绑定匹配,并 被投送到第二个队列。
(4)注意事项
主题交换机非常强大,并且可以表现的跟其他交换机相似。
当一个队列使用"#"(井号)绑定键进行绑定。它会表现的像扇形交换机一样,不理会路由键,接收所有消息。
当绑定当中不包含任何一个 “*” (星号) 和 “#” (井号)特殊字符的时候,主题交换机会表现的跟直连交换机一毛一样。
4.在rabbitMq创建好交换机:
这里创建了三种模式的交换机,分为直连模式(direct),广播模式(fanout),主题模式(topic)
5、队列绑定交换机配置类
/*** @author :Mr.ZJW* @date :Created 2023/8/30 16:08* @description:直连模式交换机配置*/
@Configuration
public class DirectRabbitConfig {/*** 队列*/public static final String DIRECT_QUERY = "directQuery";/*** 交换机*/public static final String DIRECT_EXCHANGE = "directExchange";/*** 配置队列*/@Beanpublic Queue directQuery() {return new Queue(DIRECT_QUERY, true);}/*** 配置交换机*/@Beanpublic DirectExchange directExchange() {return new DirectExchange(DIRECT_EXCHANGE);}/*** 绑定交换机*/@Beanpublic Binding bindingPushPassengerInfoToDriverExchange(@Qualifier(DIRECT_QUERY) Queue queue,@Qualifier(DIRECT_EXCHANGE) Exchange exchange) {return BindingBuilder.bind(queue).to(exchange).with(DIRECT_QUERY).noargs();}/*** 乱码配置*/@Beanpublic MessageConverter getMessageConverter() {return new Jackson2JsonMessageConverter();}
}
6、消息生产者配置类:
/*** @Author: Mr.ZJW* @Date: 2022-07-12 9:30* @Description: MQ消息发送*/
@Configuration
public class MqProduct {@Autowiredprivate RabbitTemplate rabbitTemplate;/*** 发送消息 (直连模式)** @param msg 消息* @param routingKey 消息队列Key* @return true or false*/public boolean mqDirectSend(String msg, String routingKey) {rabbitTemplate.convertAndSend(DirectRabbitConfig.DIRECT_EXCHANGE, DirectRabbitConfig.DIRECT_QUERY, msg, new MessagePostProcessor() {@Overridepublic Message postProcessMessage(Message message) throws AmqpException {//消息持久化message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);return message;}});return true;}}
7、消息消费者配置类:
/*** @Author: Mr.ZJW* @Date: 2022-07-08 16:29* @Description: MQ消费者*/
@Slf4j
@Component
public class ProductConsumer {/*** 监听司机信息给乘客** @param msg* @param message* @param channel* @throws IOException*/@RabbitListener(queues = "directQuery")public void product(String msg, Message message, Channel channel) throws IOException {try {log.info("receiver success ProductConsumer:{}", msg);log.info("唯一标识:{}", message.getMessageProperties().getCorrelationId());//手动ackchannel.basicAck(message.getMessageProperties().getDeliveryTag(), false);} catch (Exception e) {e.printStackTrace();}}}
这里配置类,不完整,可根据自行调整,交换机以及队列可动态配置,配置到配置类等。
相关文章:

RabbitMQ快速上手及讲解
前言:在介绍RabbitMQ之前,我们先来看下面一个场景: 1.1.1.1 异步处理 场景说明: 用户注册后,需要发注册邮件和注册短信,传统的做法有两种 1.串行的方式 (1)串行方式:将注册信息写入数据库后&a…...

使用多线程std::thread发挥多核计算优势(解答)
使用多线程std::thread发挥多核计算优势(题目) 单核无能为力 如果我们的电脑只有一个核,那么我们没有什么更好的办法可以让我们的程序更快。 因为这个作业限制了你修改算法函数。你唯一能做的就是利用你电脑的多核。 使用多线程 由于我们…...

MySQL分页查询详解:优化大数据集的LIMIT和OFFSET
最近在工作中,我们遇到了一个需求,甲方要求直接从数据库导出一个业务模块中所有使用中的工单信息。为了实现这一目标,我编写了一条SQL查询语句,并请求DBA协助导出数据。尽管工单数量并不多,只有3000多条,但…...

解构赋值、函数默认值
暂时性死区,TDZ(Temporal Dead Zone) var x 1 {let x x//此处声明了x,但是没有对x赋值,相当于在赋值之前引用x,所以会造成报错console.log(x)//报错x is not defined,暂时性死区,…...

【已解决】Mybatis 实现 Group By 动态分组查询
🎉工作中遇到这样一个需求场景:实现一个统计查询,要求可以根据用户在前端界面筛选的字段进行动态地分组统计。也就是说,后端在实现分组查询的时候,Group By 的字段是不确定的,可能是一个字段、多个字段或者…...

Android修改默认gradle路径
Android Studio每次新建项目,都会默认在C盘生成并下载gradle相关文件,由于C盘空间有限,没多久C盘就飘红了,于是就需要把gradle相关文件转移到其他盘 1、到C盘找到gradle文件 具体路径一般是:C:\Users\用户\ .gradle …...

原生JS+canvas实现炫酷背景
原生JScanvas实现炫酷背景 可以在需要的背景页使用 <!doctype html> <html> <head> <meta charset"utf-8"> <title>HTML5 Canvas矩阵粒子波浪背景动画特效</title> <style> html,body { height:100%; } body { …...

Linux学习之NAS服务器搭建
NAS是Network Attached Storage的缩写,也就是网络附属存储。可以使用自己已经不怎么使用的笔记本搭建一台NAS服务器。 fdisk -l可以看一下各个磁盘的状态。 可以看到有sda、sdb、sdc和sdd等四块硬盘。 lvs、vgs和pvs结合起来看,sdb和sdc没有被使用。 …...

分享码云上8个宝藏又有价值的开源图片编辑器
如果你需要高效地处理图片,那么这8款实用工具是可以尝试的! 它们能够进行一键抠图、放大、拼接、转矢量图、图标自动生成以及等操作,让你的工作效率飞升! 在Gitee这个最有价值的开源项目计划是Gitee综合评定出的优秀开源项目的展示…...

TCP Header都有啥?
分析&回答 源端口号(Source Port) :16位,标识主机上发起传送的应用程序; 目的端口(Destonation Port) :16位,标识主机上传送要到达的应用程序。 源端,目…...

无涯教程-Android - AutoCompleteTextView函数
AutoCompleteTextView是一个类似于EditText的视图,只是它在用户键入时自动显示补充数据。 AutoCompleteTextView - 属性 以下是与AutoCompleteTextView控件相关的重要属性。您可以查看Android官方文档以获取属性的完整列表以及可以在运行时更改这些属性的相关方法。…...

【Docker】 07-安装ElasticSearch、Kibana
安装ElasticSearch 1、拉取镜像 docker pull elasticsearch:6.4.2 2、运行 docker run -p 9200:9200 -p 9300:9300 --name es -d elasticsearch:6.4.2 启动会报错,按照下面流程修改 3、在宿主机中,修改配置sysctl.conf vim /etc/sysctl.conf 加入如下配…...

【数据结构篇】线性表1 --- 顺序表、链表 (万字详解!!)
前言:这篇博客我们重点讲 线性表中的顺序表、链表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列... 线性表在逻辑上是…...

C语言每日一练--Day(17)
本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字:数对 截取字符串 💓博主csdn个人主页:小小unico…...

8月琐碎但值得的事情
8月份结束了,最近心态比较好,慢点就慢点,没有那么着急了,可能是因为着急也没啥办法, 8月是比较开心的一个月,可能是做的事情更有盼头了,可能是看了喜欢的书,可能是我变瘦了ÿ…...

苹果Mac系统如何优化流畅的运行?提高运行速度
Mac系统的稳定性和流畅性一直备受大家称赞,这也是大多数人选择Mac的原因,尽管如此,我们仍不时地对Mac进行优化、调整,以使其比以前更快、更流畅地运行。以下是小编分享给各位的Mac优化方法,记得保存哦~ 一、释放被过度…...

Python 类和对象
类的创建 Python语言中,使用class关键字来创建类,其创建方式如下: class ClassName(bases):# class documentation string 类文档字符串,对类进行解释说明class_suiteclass是关键字,bases是要继承的父类,…...

VC++使用Microsoft Speech SDK进行文字TTS朗读
Microsoft Speech SDK下载地址 https://www.microsoft.com/en-us/download/details.aspx?id10121 需要msttss22L.exe、SpeechSDK51.exe、SpeechSDK51LangPack.exe三个,下载后全部安装 使用VS2005建立一个win32控制台项目 朗读"hello word"、中文“你好”…...

FFmpeg4.3.1+h264在windows下编译与VS2017项目集成
前言 在Android音视频开发中,网上知识点过于零碎,自学起来难度非常大,不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》,结合我自己的工作学习经历,我准备写一个音视频系列blog。本文是音视频系…...

mapboxGL3新特性介绍
概述 8月7日,mapboxGL发布了3版本的更新,本文带大家一起来看看mapboxGL3有哪些新的特性。 新特新 如上图所示,是mapboxGL官网关于新版的介绍,大致翻译如下: 增强了web渲染的质量、便捷程度以及开发人员体验ÿ…...

类ChatGPT大模型LLaMA及其微调模型
1.LLaMA LLaMA的模型架构:RMSNorm/SwiGLU/RoPE/Transfor mer/1-1.4T tokens 1.1对transformer子层的输入归一化 对每个transformer子层的输入使用RMSNorm进行归一化,计算如下: 1.2使用SwiGLU替换ReLU 【Relu激活函数】Relu(x) max(0,x) 。 【GLU激…...

50个简洁的提示提高代码可读性和效率(0-10)
这篇文章整理了50个简洁的提示,可以提高您的代码可读性和效率。这些提示来自个人项目、彻底的代码审查和与资深开发人员的启发性讨论。 无论您是新手还是经验丰富的开发人员,这篇文章都应该能够帮助您学到一些东西。 这个列表包括常见的Python模式、核…...

Linux —— 进程信号
一,信号概念 信号是进程之间事件异步通知的一种方式,属于软中断; 系统定义的信号 每个信号都有一个编号和一个宏定义名称(可在signal.h查看);编号34以上的为实时信号; [wz192 Desktop]$ kill -…...

Android笔记 自定义控件时drawText字符串宽度的3种计算方式
String str "hello"; canvas.drawText(str, x, y, mPaint);//1. 粗略计算文字宽度: float width mPaint.measureText(str);//2. 计算文字的矩形,可以得到宽高: Rect rect new Rect(); mPaint.getTextBounds(str, 0, str.length(…...

ChatRWKV 学习笔记和使用指南
0x0. 前言 Receptance Weighted Key Value(RWKV)是pengbo提出的一个新的语言模型架构,它使用了线性的注意力机制,把Transformer的高效并行训练与RNN的高效推理相结合,使得模型在训练期间可以并行,并在推理…...

Particle Life粒子生命演化的MATLAB模拟
Particle Life粒子生命演化的MATLAB模拟 0 前言1 基本原理1.1 力影响-吸引排斥行为1.2 距离rmax影响 2 多种粒子相互作用2.1 双种粒子作用2.1 多种粒子作用 3 代码 惯例声明:本人没有相关的工程应用经验,只是纯粹对相关算法感兴趣才写此博客。所以如果有…...

golang中byte和rune的区别?
golang中byte和rune的区别? rune和byte在go语言中都是字符类型,从源码来看他们都是别名形式 // byte is an alias for uint8 and is equivalent to uint8 in all ways. It is // used, by convention, to distinguish byte values from 8-bit unsigned…...

AI图像行为分析算法 opencv
AI图像行为分析算法通过pythonopencv深度学习框架对现场操作行为进行全程实时分析,AI图像行为分析算法通过人工智能视觉能够准确判断出现场人员的作业行为是否符合SOP流程规定,并对违规操作行为进行自动抓拍告警。OpenCV是一个基于Apache2.0许可…...

MATLAB制图代码【第二版】
MATLAB制图代码【第二版】 文档描述 Code describtion: This code is version 2 used for processing the data from the simulation and experiment. Time : 2023.9.3 Author: PEZHANG 这是在第一版基础上,迭代出的第二版MATLAB制图代码,第二版的特点是…...

5.0: Dubbo服务导出源码解析
#Dubbo# 文章内容 Dubbo服务导出基本原理分析Dubbo服务注册流程源码分析Dubbo服务暴露流程源码分析服务导出的入口方法为ServiceBean.export(),此方法会调用ServiceConfig.export()方法,进行真正的服务导出。 1. 服务导出大概原理 服务导出的入口方法为ServiceBean.export…...