笔记-《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连接都分配了缓冲区。一般来说,缓冲区越大,吞吐量也会越高,但是每个连接上耗费的内存也就越多,从而使总体服务的内存增大,这是一个权衡的问题。

相关推荐
paixiaoxin13 分钟前
学术新手进阶:Zotero插件全解锁,打造你的高效研究体验
人工智能·经验分享·笔记·机器学习·学习方法·zotero
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑1 小时前
苍穹外卖学习笔记(五)
java·笔记·学习
张望远-长风万里1 小时前
运维监控专项学习笔记-id:0-需求场景、监控作用、监控能力
运维·笔记·学习
世俗ˊ2 小时前
CSS入门笔记
前端·css·笔记
王彬泽2 小时前
【RabbitMQ】重试机制、TTL
rabbitmq·ttl·重试机制
万河归海4282 小时前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
李小星同志4 小时前
高级算法设计与分析 学习笔记6 B树
笔记·学习
霜晨月c4 小时前
MFC 使用细节
笔记·学习·mfc
Jhxbdks4 小时前
C语言中的一些小知识(二)
c语言·开发语言·笔记
AlexMercer10125 小时前
【C++】二、数据类型 (同C)
c语言·开发语言·数据结构·c++·笔记·算法