Cwww3's Blog

Record what you think

0%

mq

消息队列

  • 解耦
  • 异步
  • 流量削峰

AMQP

AMQP的全称为:Advanced Message Queuing Protocol(高级消息队列协议)。

相比JMS:

  1. JMS定义的是API规范,而AMQP定义了线路层的协议。即JMS实现所发送的消息不能保证被另外不同的JMS实现使用;而AMQP的线路层协议规范了消息的格式,这样不仅能跨AMQP实现,还能跨语言和跨平台。
  2. AMQP具有更加灵活和透明的消息模型。JMS中只有点对点和发布-订阅两种模式;而AMQP通过将消息生产者与消息队列解耦实现多种方式来发送消息。

JMS:(ActiveMQ)

  • 消息生产者
  • 消息消费者
  • 消息通道
image-20210713101139876

消息生产者将消息发送到通道中,消费者从通道中取出数据消费。

通道具有双重责任:

  1. 解耦消息的生产者与消费者;
  2. 传递数据以及确定消息发送地方。

AMQP:

在消息的生产者与通道之间引入了一种机制:Exchange(交换器),解耦了消息的生产者与队列。

image-20210713101403330

消息生产者将消息(带有一个routing key参数)发送到Exchange上,Exchange会绑定一个或多个队列上,然后Exchange根据不同的路由模式,对比队列携带的routing key参数,负责将信息发送到不同队列上。

RabbitMQ

RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写。

image-20210713105130472

Message

消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

Publisher

消息的生产者,也是一个向交换器发布消息的客户端应用程序。

Exchange

Exchange称作交换器,它接收消息和路由消息,然后将消息发送给消息队列。每个交换器都有独一无二的名字。相当于一个路由表。

Binding 和 Binding Key

每个Exchange都和一个特定的Queue绑定(可以是多对多的关系)。绑定的同时会指定一个binding key。

每个发送给Exchange的消息一般都有一个routing key参数;当队列与Exchange绑定的binding key与该消息的routing key参数相同的时候,该消息才会被Exchange发给特定的队列。

Queue

Queue是一个不重复,唯一,名字随机的的缓冲区,应用程序在其权限之内可以自由地创建、共享使用和消费消息队列。在RabbitMQ中,队列的名字是系统随机创建的,且当Consumer与Queue断开连接的时候,Queue会被自动删除,在下一次连接时又会自动创建。

Routing Key

生产者在将消息发送给Exchange的时候,一般会指定一个routing key,来指定这个消息的路由规则。
而这个routing key需要与Exchange Type及binding key联合使用才能最终生效。
在Exchange Type与binding key固定的情况下,生产者就可以在发送消息给Exchange时,通过指定routing key来决定消息流向哪里。
RabbitMQ为routing key设定的长度限制为255 bytes。

Channel

多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内地虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。

Consumer

消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。

Virtual Host

虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 / 。

Broker

表示消息队列服务器实体。

Exchange Type

AMQP定义了4种不同类型的Exchange,每一种都有不同的路由算法。

Direct

image-20210713102242328

生产者P发送消息到交换器X。

消息中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器就将消息发到对应的队列中。路由键与队列名完全匹配,单播的模式。

如果消息的routing key 是 orange,则会被路由到队列Q1;
如果消息的routing key 是 black 或 green,则会被路由到队列Q2。

也可以实现多路绑定,即当X和Q1、Q2都绑定了black,routing key 是 black 时,两个队列都能接收到消息。

image-20210713102542004

Topic

topic 交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。它将路由键和绑定键的字符串切分成单词,这些单词之间用. 隔开。它同样也会识别两个通配符:符号#和符号*#匹配0个或多个单词,*匹配一个单词。

image-20210713102637590

Fanout

每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。fanout 交换器不处理路由键,只是简单的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。fanout 类型转发消息是最快的。

生产者(P)发送到Exchange(X)的所有消息都会路由到图中的两个Queue,并最终被两个消费者(C1与C2)消费。

image-20210713103054848

Headers

headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。与direct相似,但是效率较低。

安装

erlang rabbitmq

mac 通过brew install rabbitmq 安装会自动下载erlang依赖

ARM 版 rabbitmq 路径 /opt/homebrew/sbin X86 版 /usr/local/Homebrew/sbin

添加到$PATH下

示例

项目地址

Donate comment here.