RabbitMQ 入门
一些概念
AMQP协议
AMQP 是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。目标是实现一种在全行业广泛使用的标准消息中间件技术,以便降低企业和系统集成的开销,并且向大众提供工业级的集成服务,主要实现有 RabbitMQ 。
生产者、消费者、消息
- 生产者:消息的创建者,发送到 RabbitMQ 。
- 消费者:连接到 RabbitMQ,订阅到队列上,消费消息。
- 消息:包含有效载荷和标签,有效载荷指要传输的数据,标签描述了有效载荷,并且 RabbitMQ 用它来决定谁获得消息,消费者只能拿到有效载荷,并不知道生产者是谁。
连接
首先作为客户端,无论是生产者还是消费者,你如果要与 RabbitMQ 通讯的话,你们之间必须创建一条 TCP 连接,连接在 RabbitMQ 原生客户端(5.0.0)版本中默认使用 Java 的原生 socket,但是也支持 NIO,需要手动设置修改。
信道
信道是生产者/消费者与 RabbitMQ 通信的渠道。信道是建立在 TCP 连接上的虚拟连接,什么意思呢?就是说 RabbitMQ 在一条 TCP 上建立成百上千个信道来达到多个线程处理,这个 TCP 被多个线程共享,每个线程对应一个信道,信道在 RabbitMQ 都有唯一的 ID ,保证了信道私有性,对应上唯一的线程使用。
为什么不建立多个 TCP 连接呢?
为了保证性能,系统为每个线程开辟一个 TCP 是非常消耗性能,每秒成百上千的建立销毁 TCP 会严重消耗系统,所以 RabbitMQ 选择建立多个信道(建立在 TCP 的虚拟连接)连接到 RabbitMQ 上。
虚拟主机
虚拟消息服务器,vhost,本质上就是一个 mini 版的 mq 服务器,有自己的队列、交换器和绑定,最重要的,自己的权限机制,Vhost 提供了逻辑上的分离,可以将众多客户端进行区分,又可以避免队列和交换器的命名冲突。Vhost 必须在连接时指定,RabbitMQ 包含缺省 vhost:“/”,通过缺省用户和口令 guest 进行访问。
RabbitMQ 里创建用户,必须要被指派给至少一个 vhost,并且只能访问被指派内的队列、交换器和绑定,Vhost 必须通过 RabbitMQ 的管理控制工具创建。
简单来说类似于 window 系统下的分盘,不同的盘存储不同的内容。
交换器、队列、绑定、路由键
队列通过路由键(routing key,某种确定的规则)绑定到交换器,生产者将消息发布到交换器,交换器根据绑定的路由键将消息路由到特定队列,然后由订阅这个队列的消费者进行接收(routing_key 和 绑定键 binding_key 的最大长度是 255 个字节)。
交换器类型
共有四种 Direct,Fanout,Topic,Headers,我们主要关注前3种。
Direct Exchange
直连交换器,路由键完全匹配,消息被投递到对应的队列,Direct 交换器是默认交换器,声明一个队列时,会自动绑定到默认交换器,例如 A 队列绑定路由键 routing key = juzi
,那么只有路由键为 juzi
的消息可以进入A队列。
Fanout Exchange
广播交换器,消息广播到绑定的队列,不管队列绑定了什么路由键,消息经过交换器,每个队列都有一份。
Topic Exchange
主题交换器,通过路由键配置规则转发到队列,使用 *
和 #
通配符进行处理,使来自不同源头的消息到达同一个队列,.
将路由键分为了几个标识符,*
匹配 1 个,#
匹配一个或多个。
Topic Exchange 说明
- A队列绑定了路由键
routing key = juzi.*
。 - B队列绑定了路由键
routing key = juzi.#
。 - 那么路由键为
juzi.t1
的消息会同时进入 A,B 队列。 - 路由键为
juzi.t1.t2
的消息只会进入 B 队列。
安装
使用 Docker 快速安装。
docker run -d --restart=always --hostname rabbitmq-host \
--name rabbitmq \
-e RABBITMQ_DEFAULT_USER='你的用户名' \
-e RABBITMQ_DEFAULT_PASS='你的密码' \
-v /juzi/dockerData/rabbitmq:/var/lib/rabbitmq \
-p 5672:5672 -p 15672:15672 \
rabbitmq:3.11-management