RabbitMq
1. 背景
a. AMQP-高级消息队列协议
b. 解耦
c. 方便拓展
2. 概念
A. 消费者和生产者
(1). 生产者-producer创建消息,然后发布(发送到)代理服务器(RabbitMQ)
$1. 什么是消息
a. 有效载荷(payload)
任意数据,任意格式
b. 标签(label)
描述了有效载荷,RabbitMQ通过它能决定谁能获得消息的拷贝
c. 发后即忘(fire-and-forget)的通信方式
(2). 消费者连接到代理服务器,订阅到队列上
a. 队列类似一个具名邮箱
b. 消息在到达队列后,RabbitMQ会把消息传递给其中的一个订阅/监听的消费者
c. 消息标签不会随着有效载荷一同传递
d. 如果需要得知发送方信息,只有把发送方信息放入有效载荷中
(3). 信道(生产者或消费者向服务器建立连接)
a. 建立在tcp连接内的虚拟连接
b. 每条信道都会有一个唯一的ID(AMQP库存储)
c. 避免了每次建立和销毁TCP连接会话带来的开销
d. 避免了遭遇高峰期操作系统TCP的瓶颈
e. 一次tcp连接里可以创建多条信道,既保证了线程的私密性,同时也避免了给操作系统的tcp栈带来额外负担
B. AMQP消息路由
(1). 队列
$1. AMQP消息通信的基础模块
a. 为消息提供了住所,消息在此等待消费
b .对负载均衡来说,队列是绝佳方案,只需附加一堆消费者,并让RabbitMQ以循环的方式均匀的分配发来的消息
c. 队列是RabbitMQ中消息最后的终点(除非消息进入了黑洞)
$2. 消费者通过两种方式接受特定队列里的消息
a. basic.consume 订阅
将信道设置为订阅模式,消息到达队列时自动接受
b. basic.get 单条消息
不建议放在循环里使用,影响性能
消费者应通过consume来实现高吞吐量
$3. 队列没有消费者订阅
消息在队列中等待,直到有消费者订阅,才把消息发给消费者
$4. 多消费者订阅队列
a. 机制
(1). 循环发送给消费者
(2). 每条消息只会发送给一个消费者
$5. 消费者消息确认机制
a. 命令
(1). basic.ack 显示向Rabbit发送确认
(2). auto_ack参数设置为true
b. 机制
(1). 消费者收到消息没有确认就从服务器断开连接
Rabbit会把消息传递给下一位消费者
(2). 消费者收到消息没有确认并且仍在线
不会再往该消费者发送消息了
c. 拒绝消息
(1). 从服务器断开连接
(2). RabbitMQ2.0以上版本,basic.reject
reject命令中的requeue的参数设置
为true 时 ,RabbitMQ会自动把消息传送给下一个消费者
为false时,Rabbit会从队列移除该消息,不会发送给其他消费者
$6. 队列创建
a. 须知
消费者在同一条信道上订阅另一条队列时,无法再声明队列,必须取消订阅,设置信道为传输模式
b. 队列名称
(1). 指定队列名称
(2). 不指定名称
Rabbit随机分配名称并在queue.declare命令中返回
c. 重点参数
(1). exclusive
为true时,队列变成私有的, 只有当前应用程序才能消费队列,可以用来限制一个队列只能有一个消费者
(2). auto-delete
当最后一个消费者取消订阅时,队列就会自动移除
(2). 交换器
$1. 四种类型的交换器
a. direct
如果路由建匹配,消息就被投递到对应的队列
b. fanout
将收到的消息广播到绑定的队列上
c. topic
使来自不同源头的消息到达相同的队列上
(3). 多租户于权限控制
$1. vhost 虚拟主机
a. 方便迁移
b. 数据隔离
$2. 权限控制可以在服务器上或vhost上
a.消息持久化与策略
* 必须点
(1). 消息的投递模式设置成2
(2). 发送给持久化的交换器
(3). 到达持久化的队列
b. AMQP事务
发送方确认
3. 实践
(1). 目的
$1. 解耦
$2. 提高请求处理速度
$3. 方便扩展
(2). 发后即忘模式
$1. 概念
a. 创建任务,放置到交换机上,无需知道结果
$2. 场景运用
a. 日志告警框架
b. 并行处理
(1). 执行主线任务
(2). 附带任务分开进行
(3). 实现rpc
$1. 使用消息来发回应答
a. AMQP消息头字段 reply_to
b. 生产者以该字段创建队列,并监听队列
c. 消费者检查该字段,并以该队列名称作为路由键
$2. 匿名队列