笔记-《RabbitMQ实战指南》

目录

1.发到Mq对应的3个参数:Exchange(交换器),RountingKey(路由键),param

2.队列

RabbitMq中的消息只能存在队列中,消费者从队列中获取消息并消费。

而Kafka讲消息存在topic中,对应的队列只是topic实际存储文件中的位移标识。

多个消费者订阅同一个队列时,轮询,所以也不支持队列层面的广播(可以二次开发)

3.Exchange(交换器)

RabbitMq内真实情况:

生产者将消息发送给Exchange,由交换器将消息路由到一个或多个队列。若路由不到,则返回生产者,或直接丢弃

4.Binding(绑定)

Rounting key需要与交换器类型和绑定键(BindingKey)联合起来使用。

通过绑定将交换器和队列关联。

生产者将消息发送给交换器时,需求一个RountingKey,当BindingKey和RountingKey相匹配时,消息会被路由到对应的队列中。在绑定多个队列到同一个交换器时,这些绑定允许使用相同的BindingKey。

BindingKey并不是所有的情况都生效,取决于交换器类型。

5.交换器类型

  • fanout
    把发送的消息路由到所有与该交换器绑定的队列中。
  • direct
    RountingKey与BindingKey完全匹配
  • topic
    RountingKey与BindingKey模糊匹配
    "*"用于匹配一个单词,"#"用于匹配多规格单词(可以是零个)
  • headers
    不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
    性能差,基本上不用。

6.Connection(连接),Channel(信道)

Connection,TCP连接

Channel,AMQP信道,每个信道都会被指派一个唯一 的ID。

引入信道的原因:

多Connection也可以用,但是在多线程情况下,建立多个Connection即建立多个TCP连接,而建立和销毁TCP连接是非常昂贵的,如遇使用高峰,性能也会有瓶颈。RabbitMq采用类似NIO的做法,选择TCP连接复用。

注:NIO,非阻塞IO,包含Channel,Buffer和Selector。NIO基于Channel和Buffer进行操作,数据总是从信道读取数据到缓冲区,或者从缓冲区读取到信道中。Selector用于监听多个信道的事件。因此,单线程可以监听多个数据的信道。

7. AMQP协议

包含三层:

  1. Module Layer:位于协议最高层。定义了一些供客户端调用的命令。
  2. Session Layer:位于中间层。主要负责将客户端的命令发送给服务器,再讲服务器的应答返回给客户端。为客户端和服务器之间的通信提供可靠性同步机制和错误处理。
  3. Transport Layer:位于最底层。主要传输二进制数据流,提供帧的处理,信道复用,错误检测和数据表示等。

8. 判断Channel或者Connection关闭状态

Channel或Connection中有个isOpen方法,但是有可能会产生竞争,所以并不可靠。

正确的是,在使用Channel的时候处于关闭状态的时候,会抛出ShutdownSignalException异常;Connection关闭的时候,会抛出SocketException或IOException异常。捕捉异常即可。

9. 交换器和队列的autodelete属性

交换器:当属性值设置为true时,当所有的队列断开于交换器的绑定,那么交换器会自动删除。如果从未被绑定过,则不会被删除。

队列:当所有的相关消费者断开连接时,队列将会被删除

autodelete属性针对的是曾经有过但后来没有的事物。

10.交换器的internal属性

设置是否是内置的。如果设置为true,表示是内置的交换器。客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式。

11.队列的exclusive属性

设置是否排他。为true则设置队列是排他的,则队列仅对首次 声明它的连接(Connection)可见,并在断开连接时自动删除。

同一个Connection中的Channel可以同时访问同一连接创建的排他队列。
首次 是指,如果一个连接已声明一个排他队列,则其他连接不允许创建同名的排他队列。

与普通队列不同,一旦连接关闭或客户端退出,该排他队列都会被自动删除。

这种队列适用于一个客户端同时发送和读取消息的应用场景。

12.性能

RabbitMq的消息存储在队列中,因此交换器的使用并不会真正消耗服务器的性能,而队列会。

如果要衡量RabbitMq的QPS只需要看队列即可。

13.消费模式

分为两种:推(Push)模式和拉(Pull)模式。推模式采用Basic.Consume进行消费,拉模式采用Basic.Get进行消费。

推:持续订阅

14.重新推给消费者的契机

RabbitMq不会为未确认(即autoack为false时,消费者还未返回ack)的消息设置过期时间,判断的唯一依据是该消息的消费者连接是否已经断开。

15.发送的消息丢了怎么办

两个参数:

mandatory:为true时,交换器无法根据自身的类型和路由键找到符合的队列,那么RabbitMq会调用Basic.Return命令将消息返回给生产者;为false,则消息直接丢弃。

immediate(RabbitMq现已不支持该参数的维护):为true,如果交换器在将消费路由到队列时发现队列上并不存在任何消费者,那么消息不会存入该队列。所有与路由匹配的队列都没有消费者时,会通过Basic.Return返回给生产者。

16.消息的TTL

  1. 设置队列属性,即队列中所有消息都有相同的过期时间。
    消息一旦过期,立马会从队列中抹去。队列中已过期的消息肯定在队列头部,RabbitMq只要定期从队头开始扫描是否有过期的消息即可。
  2. 对消息本身单独设置。
    即使消息过期,也不会立马从队列中抹去。每条消息的过期时间不一致,如果要删除只能扫描整个队列,所以会等到此消息即将被消费时才会判断是否过期及删除。

两种一起使用,则以两者较小的那个数值为准。

消息在队列中的时间超过TTL,则变成"死信",消费者无法再接收(不绝对)。

不设置TTL代表消息永不过期;设置为0,代表除非此时可以直接将消息投递给消费者,否则直接丢弃。

17.队列的TTL

x-expires(单位:毫秒)参数可以控制队列被自动删除前处于未使用状态的时间。未使用的意思是队列上没有任何的消费者,也没有被重新声明,并且在过期时间段内也未调用过Basic.Get命令。

会确保在过期时间到达后将队列删除,但不保障删除的动作的及时性。在RabbitMq重启后,持久化的队列的过期时间会被重新计算。

18.死信队列DLX

也叫做死信交换器或死信邮箱。

当一个消息在一个队列中变成死信后,它能被重新发送到另一个交换器中,这个交换器就是DLX,绑定DLX的队列就称之为死信队列。

消息变成死信的几种情况:

  1. 消息被拒绝(Basic.Rejext/Basic.Nack),并且设置requeue参数为false;
  2. 消息过期;
  3. 队列达到最大长度。

19.其他队列

延迟队列:存储的对象是对应的延迟消息。

优先级队列:默认最低为0。

20.持久化

  • 交换器的持久化:声明交换器时设置durable参数为true;
    若不设置持久化,则相关的交换器元数据会丢失,消息不会丢失,只是不能将消息发送到这个交换器中了。
  • 队列的持久化:声明队列时设置durable参数为true;
    若不设置持久化,则相关的队列元数据会丢失,消息也会丢失。
    队列的持久化能保证本身的元数据不会因异常情况丢失,但不能保证内部存储的消息不丢失。要确保消息不丢失,需要消息的持久化。
  • 消息的持久化。
    将投递模式deliveryMode属性设置为2即可实现消息的持久化。

21.生产者确认

  • 事务(重量级,带来性能损耗)
    RabbitMq客户端与事务机制相关的三个方法:
    1 . channel.txSelect:用于将当前信道设置为事务模式
    2 . channel.txCommit:提交事务
    3 . channel.txRollback:回滚事务
  • 发送方确认(publisher confirm)机制实现
    生产者将信道设置成confirm(确认)模式,一旦信道进入confirm模式,所有在该信道上发布的消息都会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列,RabbitMq就会发送一个确认(Basic.Ack)给生产者(包含消息的唯一ID)。
    如果消息和队列是持久化的,那确认消息会在消息写入磁盘后发出。

事务机制和confirm机制的QPS差不多,confirm机制略胜一点点。因为confirm机制也是每发送一条消息就需要等待服务端的确认,实际上是一种串行同步等待的方式。事务机制也一样,发送消息后等待服务端确认,之后再发送消息。两者的存储确认原理相同,尤其对于持久化的消息来说,两者都需要等待消息确认落盘之后才会返回。

事务机制和confirm机制是互斥的,不能共存。

事务机制和confirm机制确保的是消息能够正确的发送到RabbitMq,这里是指发动到交换器,如果此交换器没有匹配的队列,那么消息也会丢失。

优化:批量或异步。

22.消费者-消息分发策略

默认:轮询

有可能会造成整体吞吐量下降

优化:计数,每发一条消息,计数+1,消费完一条消息,计数-1。设置一个计数上限。类似于TCP/IP的滑动窗口。(对于拉模式的消费方式无效)

23.消息传输保障

一般消息中间件的消息传输保障分为三个层级

  1. At most once:最多一次。消息可能会丢失,但绝不会重复传输。
  2. At least once:最少一次。消息绝不会丢失,但可能会重复传输。
  3. Exactly once:恰好一次。每条消息肯定会被传输一次且仅传输一次。

RabbitMq支持"最多一次"和"最少一次"

24.多租户

虚拟主机(vhost):每一个RabbitMq服务器都能创建虚拟的消息服务器。每一个vhost本质上是一个独立的小型RabbitMq服务器,拥有自己独立的队列,交换器及绑定关系等,并且它拥有自己独立的权限。

RabbitMq里,权限规则是以vhost为单位的。

25.RabbitMq定制化

RabbitMq提供了三种方式来定制化服务

  1. 环境变量:shell环境中设置,或rabbitmq-env.conf配置文件
  2. 配置文件:rabbitmq.config
    配置加密,默认的Hash算法是SHA512
  3. 运行时参数和策略
    RabbitMq中一共有两种类型的Parameter:vhost级别的Parameter和global级别的Parameter。

26.RabbitMq集群

集群的所有节点都会备份所有的元数据信息:

  1. 队列元数据:队列的名称及属性
  2. 交换器:交换器的名称及属性
  3. 绑定关系元数据:交换器与队列或者交换器与交换器之间的绑定关系
  4. vhost元数据:为vhost内的队列、交换器和绑定提供命名空间及安全属性

99.其他

优化网络配置的一个重要目标就是提高吞吐量,比如禁用Nagle算法(主要用于减少延迟)、增大TCP缓冲区的大小。每个TCP连接都分配了缓冲区。一般来说,缓冲区越大,吞吐量也会越高,但是每个连接上耗费的内存也就越多,从而使总体服务的内存增大,这是一个权衡的问题。

相关推荐
鸭鸭梨吖37 分钟前
产品经理笔记
笔记·产品经理
齐 飞1 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
丫头,冲鸭!!!2 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
听忆.2 小时前
手机屏幕上进行OCR识别方案
笔记
Selina K3 小时前
shell脚本知识点记录
笔记·shell
3 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
霍格沃兹测试开发学社测试人社区3 小时前
软件测试学习笔记丨Flask操作数据库-数据库和表的管理
软件测试·笔记·测试开发·学习·flask
许苑向上4 小时前
【零基础小白】 window环境下安装RabbitMQ
rabbitmq
幸运超级加倍~4 小时前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
王俊山IT4 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习