读书笔记《RabbitMQ实战指南》(二)
2020-05-23 本文已影响0人
心似南风
书中以java语言作为示例代码,我以go语言来实现有必要记录的示例
![](https://img.haomeiwen.com/i17891001/21acb895c49db27a.png)
一、生产者(Producer)和消费者(Consumer)
- Producer生产消息(消息体和标签):
RabbitMq Broker根据标签提供的交换器名称(ExchangeName)和路由键(RoutingKey)等信息把消息发送给对应的Consumer.
- Consumer消费者接收消息(消息体),
链接到RabbitMq Broker并订阅到Queue上,消费者不知道生产者是谁。
- RabbitMq Broker消息中间件服务节点
生产者生产数据存入Broker,消费者从Broker中消费数据的整个流程:
![](https://img.haomeiwen.com/i17891001/2ff248a385303c20.png)
二、队列Queue
- rabbitMQ的消息只能存储在队列中
当多个消费者订阅同一个队列时,消息会被均摊而不是每个消费者都收到所有的消息
queueDeclare的方法详解
-
queue
: "队列名称". -
durable
: 设置是否持久化,true为持久化,持久化队列会存盘,服务器重启的时候不会丢失相关信息.
exclusive
: 设置是否排他.为true则设置队列为排他的.设置为排他队列后,,该队列仅对首次声明它的连接可见,并在连接时自动断开时自动删除. 1.排他队列基于Connecttion,其他Connecttion不允许建立同名的排他队列,即使设置了持久化,当连接断开时也会删除队列
.适用于一个客户端同时发送和读取消息的应用场景. -
autoDelete
: true设置自动删除,前提:至少有一个消费者连接到这个队列,之后与这个队列连接的消费者都断开时,才会自动删除,不能错误的理解为: 当连接到此队列的所有客户端断开时,这个队列自动删除,因为生产者创建这个队列,或者没有消费者客户端与这个队列连接时,都不会删除这个队列
-
args
: 设置队列的其他一些参数,如: x-message-ttl, x-expires, x-max-length, x-max-length-bytes, x-dead-letter-exchange, x-dead-letter-routing-key, x-max-priority等(TODO)
三、交换器(Exchange)、路由键(RoutingKey)、绑定(Binding)
- 交换器:将生产者的消息路由队列中,如果路由不到会返回给生产者或直接丢掉
-
交换器四个类型:
1)fanout
:把发送到该交换器的消息路由到所有与该交换器绑定的队列中。
2)direct
:把消息路由到BingKey和RoutingKey完全匹配的队列中。
3)topic
: BingKey与RoutinKey的匹配规则为BindingKey的字符规则: `*`用于匹配一个单词 `#`用于匹配多个单词(可以时零个) 如 RoutingKey为: com.rabbitmq.client 会被 路由到BindingKey为 *.rabbitmq.* 的队列中
4)
headers
:根据发送消息内容的headers属性进行匹配,headers类型的交换器性能很差,而且不实用
。 -
mandatory
:当交换器无法根据自身的类型和路由键找到符合条件的队列时,设置true则返回给生产者,设置false则直接将消息丢掉 -
immediate
:如果关联的队列上有消费者则立即投递,如果所有匹配的队列都没有消费者,则直接将消息返回给生产者,不用将消息存入队列等待消费者了。(3.0版本去掉了)官方解释:影响镜像队列的性能,增加代码复杂性,建议采用TTL和DXL方法替代。
ExchangeDeclare方法参数:
- durable:设置是否持久化。true表示持久化,反之非持久化。持久化可以将交换器存盘,在服务器重启的时候不会丢失相关信息。
- autoDelete: 设置true表示自动删除。自动删除的前提是至少有一个队列或者交换器与这个交换器绑定,之后所有与这个交换器绑定的队列或者交换器都与此解绑。
注意不能错误的理解为:“当与此交换器链接的客户端断开时,RabbitMq会自动删除本交换器”
-
internal
: 设置是否内置的。如果设置为true,则表示是内置的交换器,客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这中方式。 -
argument
: 其他一些结构化参数,比如alternate-exchange(设置备份交换器) -
alternate-exchange
: 备份交换器设置参数,建议将此交换器设置为fanout类型。参考图很详细,
借用网上的参考图:
![](https://img.haomeiwen.com/i17891001/b0c291c262206964.png)
- 路由键:routingKey用来指定消息的路由规则,与交换器类型和bingKey联合使用才能生效。
- Binding:将交换器与队列关联起来,绑定时指定RoutingKey,当Routing与BindingKey相匹配时,消息会路由到对应的队列中。
# 发送消息到队列中
err = r.channel.Publish(
r.ExchangeName,
// 如果为true, 根据exchange类型和routkey规则,如果无法找到符合条件的队列,那么会把发送的消息返回给发送者
r.RoutingKey,
false,
// 如果为true, 当exchange发送消息到队列后发现队列上没有绑定消费者,则会把消息发还给发送者(RabbitMq3.0去掉了该参数的支持,官方解释为该参数影响镜像队列的新能,增加了代码的复杂度建议采用TTL和DLX方法替代)
false,
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(message),
})
# 绑定队列到 exchange 中
err = r.channel.QueueBind(
q.Name,
//需要绑定key
r.RoutingKey, // 此处为BindingKey需与RoutingKey相同
r.ExchangeName,
false,
nil)
r.checkError(err, "Failed to bind a queue")
}
四、AMQP协议
生产者将消息发送给交换器,交换器和队列绑定,生产者发送消息携带的RoutingKey和绑定的BindingKey相匹配时,消息即被存入相应的队列之中。消费者可以订阅相应的队列获取信息。
AMQPx协议包括三层:
- Module Layer:位于协议最高层,主要定义了一些供客户端调用的命令,客户端可以利用这些命令实现业务逻辑。
- Session Layer:位于中间层,将客户端的命令发送给服务端,再将服务端的应答返回给客户端(为通信提供可靠性同步机制和错误处理)
- Transport Layer: 位于最底层,传输二进制数据流,提供帧处理,信道复用,错误检测和数据表示