消息队列项目基础知识总结

什么是消息队列(Message, Queue,MQ)

阻塞队列(Blocking Queue) ->生产者消费者模型(是在一个进程内部进行的)

所谓的消息队列,就是把阻塞队列这样的数据结构,单独提取成了一个程序,进行独立部署 => 生产者消费者模型(进程和进程之间/服务与服务之间)

生产者消费者模型的作用:

1.解耦合

本来有个分布式系统 A 服务器调用 服务器 B (A 给 B 发送请求, B 给 A 返回响应) => 此时的 A 和 B 之间的耦合比较大,引入消息队列之后,A 把消息发给队列, B 在从消息队列中获取到请求,写代码追求的是 "高内聚,低耦合"

2.削峰填谷

比如 A 是入口服务器, A 在调用 B 完成一些列具体的业务,如果 A 和 B 之间是直接通信, 如果 A 突然收到了一组用户请求的峰值,此时也 B 也会感受到峰值

引入消息队列之后,A 把请求发送给队里 B , B 在队列中获取请求, 虽然 A 收到的请求有很多,队列中收到的请求也不少,但是 B 任然可以按照原有的节奏去获取请求,不至于说请求一下子过多导致服务器挂掉

市面上比较知名的MQ:

RabbitMQ, Kafka, RocketMQ, ActivieMQ

需求分析:

核心概念:

1.生产者(Producer)

2.消费者(Consumer)

3.中间人(Broker)

4.发布(Publish)

5.订阅(Subscribe)

6.消费(Consume)

生产者向中间人这里投递消息的过程就叫"发布", 哪些消费者要从这个中间人这里取数据,这个注册的过程,称为"订阅",消费者从中间人这里读取数据的动作叫"消费"

这个中间人叫 "BrokerServer"

BrokerServer 内部也设计到一些关键的概念(MQ)

1.虚拟主机(Virtual Host) :

类似于 MySQL 中的databaes, 算是一个逻辑上的数据集合一个 Broker Server 上也可以组织多种不同类型的数据,可以使用 Virtual Host 做出区分

2.交换机(Exchange)

生产者把消息投递给 BrokerServer 实际上是,先把消息交给了 BrokerServer 上的某个交换机,再由交换机把消息转发给对应的消息队列

3:队列(Queue)

真正的用来存储消息实体的,后续消费者也是从对应的队列中获取数据,一个大的消息队列中,可以由很多具体的小队列

4.绑定(Binding)

把交换机和队列之间,建立起来关联关系,可以把 交换机 和 队列 类似于数据库 中的 "多对多" 这样的关系,一个交换机,可以对应到多个队列,一个队列也可以对应到多个交换机

5.消息(Message)

具体的来说, 可以认为是服务器 A 给 B 发的请求(通过 MQ 转发), 就是一个消息,服务器 B 给 A 返回的响应(通过 MQ 转发), 也是一个消息

一个消息,可以视为是一个字符串(二进制数据).消息中具体包含啥样的数据,都是人为规定的

消息队列服务器(BrokerServer),要提供的核心API

1.创建队列(queueDeclare)

2.销毁队列(queueDelete)

3.创建交换机(exchangeDelete)

4.销毁交换机(exchangeDelete)

5.创建绑定(queueBind)

6.解除绑定(queueUnbind)

7.发布消息(basicPublish)

8.订阅消息(basicConsume)

9.确认消息(basicAck)

创建队列(queueDeclare) 这里不使用 Create 这样的术语,而是使用 Declare ,Create只是表示单独的"创建", Declare 起到的效果是:不存在则创建,存在就不用做了

确认消息(basicAck) 起到的效果,是可以让消费者显示的告诉 BrokerServer ,这个消息我已经处理完毕了,提高了整个系统的可靠性,保证消息处理没有遗留

对于 MQ 和 消费者 之间的工作模式 有两种:

1.Push(推) BrokerServer 把收到的数据,主动的发送给订阅的消费者,

2.Pull(拉) 消费者主动的调用 BrokerServer 的 api 取数据

在RabbitMQ 中只支持 推 的模式

交换机类型

交换机在转发消息的时候,就有一套转发的规则,提供了几种不同的 交换机类型(Exchange Type) 来描述这里不同的转发规则

RabbitMQ 主要实现了下述四种交换机类型(也是 AMQP 协议定义的)

1.Direct 直接交换机

2.Fanout 扇出交换机

3.Topic 主题交换机

4.Header 消息交换机

我们在项目中通常实现的是前三种

1.Direct 直接交换机

生产者发送消息的时候,就会指定一个"目标队列的名字",交换机收到之后,就会看看绑定的队列里,有没匹配的队列,如果有,转发过去(把消息队列塞进对应的队列中),如果没有,消息就直接丢弃

2.Fanout扇出交换机

群发

3.Topic主题交换机

有两个关键的概念

1)bindingKey:把队列和交换机绑定的时候,指定一个单词(像是一个暗号一样)

2)routingKey:生产者发送消息的时候也指定一个单词

如果当前的 bindingKey 和 routingKey能够对上暗号,此时就可以把这个消息转发到对应的队列中

持久化

虚拟主机, 交换机, 队列, 绑定, 消息, 都是需要让BrokerServer 组织管理的

上述的这些概念对应的数据,需要存储和管理起来,此时的内存和硬盘上都各自都会存储一份,一内存为主,硬盘为辅

在内存中存储的原因:对于 MQ 来说,能高效的转发处理数据,是非常关键的指标,因此使用内存来组织上述数据,得到的效率,就比放硬盘中要高很多

在硬盘中要存储的原因:为了防止内存中的数据随着进程的重启/主机重启而丢失

网络通信

其他的服务器(生产者/消费者)通过网络,和我们的 BrokerServer 进行交互的,此处设定,使用 TCP + 自定义的应用层协议,实现生产者消费者模型 和 BrokerServer 之间的交互工作

自定义的应用层协议:这里的工作是,让客户端可以通过网络,调用 BrokerServer 提供的编程接口,因此,在客户端这边,也需要提供对应的上述这些方法,只不过服务器版本的上述方法,效果是真正的干实事,把管理数据进行调整,客户端这边上述的方法,则只是发送请求/接受响应

1.创建队列(queueDeclare),销毁队列(queueDelete),创建交换机(exchangeDeclare),销毁交换机(ExchangeDelete),创建绑定(queueBind),解除绑定(queueUnbind),发布消息(basicPublic),订阅消息(basicConsume),确认消息(basicAck)

客户端除了提供上述的9个服务器这边对应的方法之外还要需要再提供四个方法,支撑其他工作

1.创建(Connection)

2.关闭(Connection)

一个 Connection 就代表一个TCP连接

3.创建(Channel)

4.关闭(Channel)

这两个代表的是通信/信道

一个 Connection 里面可以包含很多个 Channel 每个 Channel 上面传输的数据是互不相干的

TCP,建立/断开一个连接,成本其实是比较高的,因此,很多时候是不希望频繁的建立断开 TCP 连接, Channel 只是一个逻辑上的概念,比 TCP 连接的建立和断开,轻量很多

生产者客户端和 BrokerServer之间的联系

生产者客户端发送请求(包含了,创建队列的命名,以及队列的详细描述)

生产者代码中就需要调用一个方法,queueDeclare来创建队列,生产者这边需要提供一个 queueDeclare 方法这个方法内部要做的事情,就是给服务器发送一个请求,告诉服务器,咱们要创建一个队列出来,然后介绍这个队列具体的详细信息

BrokerServer 收到这个请求之后,再执行服务器这边的 queueDeclare 方法,真正的去给 内存/硬盘上写数据,把这个队列真正的创建出来,在把创建成功/失败 结果包装成响应,返回给客户端

当响应回来了,客户端的 queueDeclare 就会获取到这个响应,此时队列创建成功,此时的queueDeclare 就算执行完毕

此处,客户端调用了一个本地的方法,结果这个方法在背后,给服务器发了一些列的消息,由服务器完成一系列工作,站在调用者角度看到的只是说,当前这个功能已经完成,并不知道这背后的细节,虽然调用的是一个本地的方法,实际上更像是调用了一个远端的服务器的方法一样

具体细化一下要完成的工作

1.实现生产者, BrokerServer, 消费者 这三个部分的

2.针对生产者和消费者来说,主要编写的是 客户端和服务器 的网络通信部分,给客户端提供了一组 api,让客户端的业务代码来调用,从而通过网络通信的方式远程调用 BrokerServer 上的方法

3.[重点] 实现 BrokerServer 以及 BrokerServer 内部的一些基本概念和核心api

基本概念指:虚拟主机(Virtual Host), 交换机(Exchange), 队列(Queue),绑定(Binding),消息(Message) 在硬盘和内存中都分别组织好

核心 api 指的是:创建交换机,删除交换机,创建队列,删除队列,创建绑定,解除绑定,发送消息,订阅消息,应答消息

4.持久化:上述这些关键数据,在硬盘中怎么存储,啥格式存储,存储在数据库文件中,后续服务器重启了,如何读取上述的数据,把内存中的内容恢复回来

相关推荐
历程里程碑2 小时前
Linux 5 目录权限与粘滞位详解
linux·运维·服务器·数据结构·python·算法·tornado
酉鬼女又兒2 小时前
SQL113+114 更新记录(一)(二)+更新数据知识总结
java·服务器·前端
zuozewei2 小时前
零基础 | AI应用记忆管理:从短期到长期的完整实践指南
运维·服务器·人工智能
jghhh012 小时前
MATLAB分形维数计算:1D/2D/3D图形的盒维数实现
数据库·matlab
馨谙2 小时前
shell编程实际应用----磁盘空间监控与告警
linux·运维·服务器
跃渊Yuey2 小时前
【Linux】线程概念
linux
njsgcs2 小时前
MiniCPM4-0.5B-QAT-Int4-GPTQ-format 小显存llm
linux·人工智能
UP_Continue2 小时前
Linux--命令行参数和环境变量
linux·运维·服务器
重生之绝世牛码3 小时前
Linux软件安装 —— PostgreSQL高可用集群安装(postgreSQL + repmgr主从复制 + keepalived故障转移)
大数据·linux·运维·数据库·postgresql·软件安装·postgresql高可用