RabbitMQ基础_1.基本介绍

一、 初识MQ

1.1、 同步通讯和异步通讯

微服务间通讯有同步和异步两种方式:

  • 同步通讯:就像打电话,需要实时响应。
  • 异步通讯:就像发微信,不需要马上回复。

在这里插入图片描述

1.1.1、 同步通讯

  我们之前在SpringCloud学习的Feign调用就属于同步方式,虽然调用可以实时得到结果,但存在下面的问题:
在这里插入图片描述

1.1.2、 异步通讯

异步调用常见实现就是事件驱动模式:
在这里插入图片描述
异步通讯的优势如下:

1.服务解耦(如果想要加新需求,直接让新需求模块订阅broker消息就好,与支付服务无关)

在这里插入图片描述
2.性能提升,吞吐量提高(只需要等待60ms,而同步方式需要等待每一个下游服务都处理完)

在这里插入图片描述
3.服务没有强依赖,不担心级联失败问题(例子:即使仓储服务挂掉,也不会发生像同步方式,支付服务一直等待的现象)

在这里插入图片描述
4.流量削峰(当请求量增大时(并发增大),将消息存到broker处,让下游服务有序进行)

在这里插入图片描述
实现下图的效果:

在这里插入图片描述


5.日志收集:将日志信息发送到消息队列,实现集中式的日志管理和统计分析。

1.2、 MQ优缺点对比

  MQ (MessageQueue),中文是消息队列,字面来看就是存放消息的队列。也就是事件驱动架构中的Broker

1.2.1、 ActiveMQ

我们先看ActiveMQ。其实一般早些的项目需要引入消息中间件,都是使用的这个MQ,但是现在用的确实不多了,说白了就是有些过时了。我们去它的官网看一看,你会发现官网已经不活跃了,好久才会更新一次。

它的单机吞吐量是万级,一些小的项目已经够用了,但对于高并发的互联网项目完全不够看。

在高可用上,使用的主从架构的实现。

在消息可靠性上,有较低的概率会丢失数据。

综合以上,其实这个产品基本可以弃用掉了,我们完全可以使用RabbitMQ来代替它。

1.2.2、 RabbitMQ

RabbitMQ出现后,国内大部分公司都从ActiveMQ切换到了RabbitMQ,基本代替了activeMQ的位置。它的社区还是很活跃的。

它的单机吞吐量也是万级,对于需要支持特别高的并发的情况,它是无法担当重任的。

在高可用上,它使用的是镜像集群模式,可以保证高可用。

在消息可靠性上,它是可以保证数据不丢失的,这也是它的一大优点

同时它也支持一些消息中间件的高级功能,如:消息重试、死信队列等。

但是,它的开发语言是erlang,国内很少有人精通erlang,所以导致无法阅读源码。对于大多数中小型公司,不需要面对技术上挑战的情况,使用它还是比较合适的。而对于一些BAT大型互联网公司,显然它就不合适了。

1.2.3、 RocketMQ

接下来我们来讨论一下我比较喜欢的RocketMQ,它是阿里开源的消息中间件,久经沙场,非常靠谱。

它支持高吞吐量,能达到10万级,能承受互联网项目高并发的挑战。

在高可用上,它使用的是分布式架构,可以搭建大规模集群,性能很高。

在消息可靠性上,通过配置,可以保证数据的绝对不丢失。

同时它支持大量的高级功能,如:延迟消息、事务消息、消息回溯、死信队列等等。

它非常适合应用于java系统架构中,因为它使用java语言开发的,我们可以去阅读源码了解更深的底层原理。

目前来看,它没有什么特别的缺点,可以支持高并发下的技术挑战,可以基于它实现分布式事务,大型互联网公司和中小型公司都可以选择使用它来作为消息中间件使用,如果我来做技术选型,我首选的中间件就是它。

1.2.4、 Kafka

kafka的吞吐量被公认为中间件中的翘楚,单机可以支持十几万的并发,相当强悍。

在高可用上同样支持分布式集群部署。

在消息可靠性上,如果保证异步的性能,可能会出现消息丢失的情况,因为它保存消息时是先存到磁盘缓冲区的,如果机器出现故障,缓冲区的数据是可能丢失的。

它的功能非常的单一,就是消息的接收与发送,因此不适合应用于许多场景。

它在行业内主要应用于大数据领域,使用它进行用户行为日志的采集和计算所以,如果没有大数据的需求,一般不会选择它


在这里插入图片描述

二、 RabbitMQ_基础

2.1、 为什么选择RabbitMQ

  • ActiveMQ,性能不是很好,因此在高并发的场景下,直接被pass掉了。它的 Api 很完善,在中小型互联网公司可以去使用。
  • kafka主要强调高性能,如果对业务需要可靠性消息的投递的时候。那么就不能够选择kafka了。但是如果做一些日志收集呢,kafka还是很好的。因为kafka的性能是十分好的。
  • RocketMQ,它的特点非常好。它高性能、满足可靠性、分布式事务、支持水平扩展、上亿级别的消息堆积、主从之间的切换等等。MQ的所有优点它基本都满足。但是它最大的缺点:商业版收费。因此它有许多功能是不对外提供的。

2.2、 RabbitMQ简介

  RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。AMQP :Advanced Message Queue Potocal,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。RabbitMQ最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

2.3、 RabbitMQ架构

在这里插入图片描述

  • Broker(服务器):即RabbitMQ Server,也叫Broker server,接收和分发消息的应用,保证数据能够按照指定的方式进行传输。
  • Connection(连接):Producer/Consumer 和 broker 之间的 TCP 连接,在消息发送时必须要先建立与RabbitMQ服务器的连接。
  • Channel(信道):建立在Connection中,消息是基于Channel传递的,Channel之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销;如果每一次访问RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection的开销将是巨大的,效率也较低。
  • VirtualHost(虚拟主机):exchange/queue是属于某个VirtualHost的,VirtualHost属于某个用户的;VirtualHost可以分配用户在创建交换机或队列时可以指定其属于哪个虚拟主机,方便用户管理交换机和队列。
  • Producer(生产者): 消息的生产者,数据的发送方。消息生产者连接RabbitMQ服务器然后将消息投递到Exchange。
  • Exchange(交换机):生产者将消息发送到 Exchange(交换器),由 Exchange将消息路由到一个或多Queue 中(或者丢弃)。Exchange 并不存储消息。RabbitMQ 中的 Exchange 有directfanouttopicheaders 四种类型,每种类型对应不同的路由规则。
  • Queue(队列):是RabbitMQ的内部对象,用于存储消息。消息消费者就是通过订阅队列来获取消息;RabbitMQ 中的消息都只能存储在Queue中,生产者生产消息并最终投递到Queue 中,消费者可以从 Queue 中获取消息并消费。多个消费者可以订阅同一个Queue,这时 Queue中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理。
    在这里插入图片描述

2.4、 交换机类型

2.4.1、 Direct Exchange(直连交换机)

在这里插入图片描述
  直连交换机的特点是消息队列通过routingKey与交换机进行绑定,相同的routingKey会获得相同的消息。一个队列可以通过多个不同的routingKey与交换机进行绑定。不同的队列也可以通过相同的routingKey绑定交换机。

2.4.2、 Fanout Exchange(扇出交换机)

在这里插入图片描述
  扇出交换机的特点是类似于广播,只要队列与该类型的交换机绑定,所有发送到该交换机的信息都会被转发到所有与之绑定的队列,与routingKey无关。

2.4.3、 Topic Exchange(主题交换机)

在这里插入图片描述
  应用范围最广的交换机类型,消息队列通过消息主题与交换机绑定。一个队列可以通过多个主题与交换机绑定,多个消息队列也可以通过相同消息主题和交换机绑定。并且可以通过通配符(*或者#)进行多个消息主题的适配。

  消息主题的一般格式为xxx.xxx.xxx(x为英文字母,每个单词用英文句号隔开)。*通配符可以适配一个单词,#可以适配零个或者多个单词。

2.4.4、 Header Exchenge(头交换机)

在这里插入图片描述
  与routingKey无关,匹配机制是匹配消息头中的属性信息。在绑定消息队列与交换机之前声明一个map键值对,通过这个map对象实现消息队列和交换机的绑定。当消息发送到RabbitMQ时会取到该消息的headers与Exchange绑定时指定的键值对进行匹配;如果完全匹配则消息会路由到该队列,否则不会路由到该队列。

匹配规则x-match有下列两种类型:

  • x-match = all :表示所有的键值对都匹配才能接受到消息
  • x-match = any :表示只要有键值对匹配就能接受到消息

引用:
1.Rabbitmq的四种类型交换机

2.5、 RabbitMQ工作模式

RabbitMQ官网地址:里面有介绍RabbitMQ的工作模式。

2.5.1、 Hello World

在这里插入图片描述
  简单模式中表现为一个生产者对应一个消费者,生产者(Producer)生产消息发送到队列,消费者(Consumer)监听此队列,进行消息的消费;

2.5.2、 Work Queues

在这里插入图片描述
  Work模式与Simple模式几乎是一模一样的,只不过我们在只有一个Producer和一个Consumer时习惯把这种模式称为Simple模式,而当一个Producer有多个Consumer时我们把这样的模式成为Work模式,因此Work模式和Simple模式的代码是一模一样的,只不过是多个Consumer监听同一个队列而已(一个队列下的Consumer是竞争关系);

2.5.3、 Publish/Subscribe

在这里插入图片描述
  在发布订阅模式中,Producer发送消息到指定的Exchange中,由Exchange绑定不同的Queues,消费者依旧监听这些队列进行消费。
  发布订阅模式重点强调的是fanout类型的Exchange,发布订阅模式也叫分列模式;

需要注意的两点:
1、work、simple也会有交换机,他们使用的是默认的交换机
2、Exchange还可以绑定到另一个Exchange上

2.5.4、 Routing

在这里插入图片描述
  发布订阅模式强调的是Fanout类型的Exchange,Routing模式则强调的是direct类型的Exchange,Routing模式也叫直连模式;
  如上图所示,如果消息的路由键是orange,则此消息只会到队列Q1上;如果消息的路由键为black或green,则此消息会到队列Q2上。实际工作中,90%都是使用的此模式

2.5.5、 Topics

在这里插入图片描述
  Topics模式也叫主题模式,相比于发布订阅模式,该模式下的Exchange在绑定Queues时可以指定的一定的通配符,这些通配符指定了路由的规则;

  • 符号 #:匹配零个或多个词。(0个或多个)
  • 符号 *:匹配不多不少一个词。(必须是一个,0个不行)

2.5.6、 RPC

《RabbitMQ系列教程-第四章-06-RabbitMQ工作模式之RPC模式》

2.5.7、 Publisher Confirms

这部分比较复杂,放到后面介绍。

这是我之前做过的一个项目,把这个设计结构有用的也加入到之前的项目中,做一个最全的:后端项目结构深度解析:testrealend 项目 一、项目根目录核心文件 plaintext testrealend/ ├── app.py # Flask应用主入口 │ api # 职责:创建应用实例、配置扩展、注册API路由 ├── requirements.txt # 依赖包清单(pip install -r 安装) ├── add_user_script.py # 管理员账户初始化脚本 ├── update_user_script.py # 用户信息更新脚本 ├── temp_qrcode.png # 临时二维码图片(水印功能相关) ├── embed/ # 水印嵌入后ZIP文件存储目录 │ # 文件名格式:员工ID_时间戳_嵌入结果.zip ├── compare/ # 水印比对文件目录(原始/提取水印对比) ├── static/ # 静态资源目录(CSS/JS/图片,当前项目未直接使用) └── templates/ # HTML模板目录(后端渲染页面时使用,当前项目为空) 二、核心功能模块解析 (1)API 接口层:resource/ plaintext src/resource/ ├── common_resource.py # 通用接口:注册(Register)、登录(Login)、登出(Logout) ├── adm_resource.py # 管理员接口:员工管理、水印操作 ├── emp_resource.py # 员工接口:数据申请、下载、查看 ├── shp_data_resource.py # SHP数据接口:列表查询、ID检索(重点修改模块) ├── application_resource.py # 数据申请接口:提交/审批流程 ├── nav_resource.py # 导航菜单接口:权限动态渲染 ├── generate_watermark.py # 水印生成接口:二维码/文本转水印 ├── embed_watermark.py # 水印嵌入接口:SHP文件处理 ├── download_file_resource.py # 文件下载接口:权限控制 ├── receive_zip_to_extract.py # ZIP上传接口:解压与验证 └── __init__.py # 包初始化文件 核心逻辑: • 每个.py文件对应一类业务场景,通过Flask-RESTful的Resource类定义 HTTP 接口(GET/POST/PUT/DELETE) • 接口路径通过api.add_resource(ResourceClass, '/api/path')在app.py中注册 (2)业务逻辑层:server/ plaintext src/server/ ├── shp_data_server.py # SHP数据业务逻辑:数据库查询、文件处理 ├── adm_server.py # 管理员业务逻辑:账户管理、权限校验 ├── emp_server.py # 员工业务逻辑:数据权限控制 ├── common_server.py # 通用业务逻辑:用户认证、 token管理 ├── application_server.py # 数据申请业务逻辑:流程状态管理(注意:拼写应为application) └── __init__.py # 包初始化文件 设计模式: • 资源类(Resource)接收请求后,调用对应服务类(Server)的方法执行具体逻辑 • 实现接口层与业务层解耦,便于单元测试和逻辑复用 (3)数据模型层:model/ plaintext src/model/ ├── Shp_Data.py # SHP文件模型:存储文件元信息(路径/属性/状态) ├── Adm_Account.py # 管理员账户模型:用户名/密码哈希/权限等级 ├── Employee_Info.py # 员工信息模型:基本资料/部门/角色 ├── Application.py # 数据申请模型:申请记录/审批状态/时间戳 └── __init__.py # 包初始化文件 技术细节: • 使用SQLAlchemy ORM映射数据库表,支持db.Model继承 • 字段定义包含String/Integer/DateTime等类型,部分字段设置unique/index索引 (4)算法模块:algorithm/ plaintext src/algorithm/ ├── NC.py # 归一化相关系数算法(水印相似度计算) ├── embed.py # 水印嵌入算法:SHP文件空间域修改 ├── extract.py # 水印提取算法:信号检测与解码 ├── get_coor.py # 坐标提取工具:从SHP获取几何坐标 ├── is_multiple.py # 倍数判断工具:坐标精度处理 ├── to_geodataframe.py # 地理数据转换:SHP转GeoDataFrame ├── embed/ # 水印嵌入测试数据目录 └── __init__.py # 包初始化文件 (5)扩展与工具:extension/ & utils/ • extension/ plaintext src/extension/ ├── extension.py # 扩展初始化:db(SQLAlchemy)/limiter(请求限流) └── __init__.py • utils/ plaintext src/utils/ ├── required.py # 请求参数校验:必填字段检查 └── __init__.py (6)通用工具:common/ plaintext src/common/ ├── api_tools.py # API辅助函数:响应格式化/错误处理 ├── constants.py # 项目常量:状态码/路径前缀/权限标识 └── __init__.py 三、数据库与配置模块 (1)数据库迁移:migrations/ plaintext src/migrations/ ├── alembic.ini # Alembic配置文件 ├── env.py # 数据库连接配置(生产/开发环境区分) ├── script.py.mako # 迁移脚本模板 └── versions/ # 具体迁移脚本目录(每个版本一个.py文件) 使用场景: • 模型变更时通过flask db migrate生成脚本,flask db upgrade更新数据库 (2)IDE 配置与缓存:.idea/ & pycache/ • .idea/:PyCharm 项目配置(勿手动修改,已加入.gitignore) • __pycache__/:Python 字节码缓存(自动生成,提升模块加载速度)
最新发布
07-03
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值