-
RabbitMQ
的应用场景以及基本原理介绍
1.
背景
RabbitMQ
是一个由
erlan
g
开发的
AMQP(Advanved
Message
Queue)
的开源实现。
2.
应用场景
2.1
异步处理
场景说明:
用户注册后,
需要发注册邮件和注册短信
,
传统的
做法有两种
1.
串行的方式
;2.
并行的方式
p>
(1)
p>
串行方式
:
将注册信息写入数据库后
,
发送注册邮件
,
再
发
送注册短信
,
以上三个任务全部完成
后才返回给客户端。
这
有一个问题是
,
邮件
,
短信
并不是必须的
,
它只是一个通知
,
p>
而
这种做法让客户端等待没有必要等待的东西
.
(2)
并行方式
:
将注册信息写入数据库后
,
发送
邮件的同时
,
发
送短信
,
以上三个任务完成后
,
返回
给客户端
,
并行的方式能提
高处理的时
间。
假设三个业务节点分别使用
50ms,
串行方式使用时间
150ms,<
/p>
并行使用时间
100ms
。虽然并性已经
提高的处理时
间
,
但是
,
前面说过
,
邮件和短信对我
正常的使用网站没有任何
影响,
客户端没有必要等着其发送完成
才显示注册成功
,
英爱
是写入数据库后
就返回
.
(3)
消息队列
引入消息队列后,
把发送邮件
,
短信不是必须的业务逻辑异步
处理
由此可
以看出
,
引入消息队列后,
用户的响应
时间就等于写入
数据库的时间
+
写入消
息队列的时间
(
可以忽略不计
),
p>
引入消
息队列后处理后
,
< br>响应时间是串行的
3
倍
,
是并行的
2
倍。
2.2
应用解耦
< br>场景:
双
11
是购物狂节
,
用户下单后
,
订单
系统需要通知库存
系统
,
传统的做法就
是订单系统调用库存系统的接口
.
这种做法有一个缺点
:
当库存系统出
现故障时
,
订单就会失败。
(
这样马云将少赚好
多好多钱
^
^)
订单系统和库存系统高耦合
.
引入消息队列
订单系统
:
用户下单后
,
订单系统完成持久化处
理
,
将消息写入
消息队列
,
返回用户订单下单成功。库存系统
:
订阅下单的消
息
,
获取下单
消息
,
进行库操作。
就算库存系统出现故障
,
消息队列也能保证消息的可靠投递
,
不会导致消息丢失
(
马云这下高兴了
).
流量削峰
流量削峰一般在秒杀活动中应用广泛
场景
:
秒杀
活动,一般会因为流量过大,导致应用挂掉
,
为了
解决这个问题,一般在应用前端加入消息队列。
作用
:
1.
可以控制活动人数,
超过此一定阀值的订单直接丢弃
(
我为
什么秒杀一次都没有成功过呢
^^)
2.
可以缓解短时间的高流量压垮应
用
(
应用程序按自己的最
大处理能力获
取订单
)
1.<
/p>
用户的请求
,
服务器收到之后
,
首先写入消息队列
,
加
入消息
队列长度超过最大值
,
则直接抛
弃用户请求或跳转到错误页
面
.
2.
秒杀业务根据消息队列中的请求
信息,再做后续处理
.
3.
系统架构
几个概念说明
:
Broker:
它提供一种传输服务
,
它的角色就是维护一条从生产
者到消
费者的路线,保证数据能按照指定的方式进行传输
,
Exchange
:消息交换机
p>
,
它指定消息按什么规则
,
路由到哪个
队列。
Queue:
消息的载体
,
每个消息都会被投到一个或多个队列。
Binding:
绑定,它的作用就是把
exchange
和
queue
按照路
由规则绑定起来
.
Routing K
ey:
路由关键字
,exchange
根据这个关键字进行消
息投递。
vhost:
虚拟主机
,
一个
broker
里可以
有多个
vhost
,用作不同
用户的权
限分离。
Producer:
消息生产者
,
就
是投递消息的程序
.
Consumer:
消息消费者
,
就是接受消息的程序
.
Channel:
消息通道
,
在客户端的每个连接里
,
可建立多个
channel.
4.
任务分发机制
4.1Round-robin
dispathching
循环分发
RabbbitMQ
的分发机制非常适合扩展
,
而且它是专门为并发
程序设计的
,
如果现在
load
加重
,
那么只需要创建更多的
Consumer
来进行
任务处理。
4.2Message
acknowledgment
消息确认
为了保证数据不被丢失
,RabbitMQ
支持消息确认机
制
,
为了
保证数据能被正确处理而不仅
仅是被
Consumer
收到
,
那么
我们不能采用
no-ack
,
而应该是在处理完数据之后发送
ack.
在处理完数据之后发送
ack,
就是告诉
RabbitMQ
数据已经被
接收
,
处理完成
,RabbitMQ
可以安全的删除它了
.
如果
Consumer
退出了但是没有发送
ack,
那么
RabbitMQ
就
会
把这个
Message
发送到下一个
C
onsumer
,
这样就保证在
Con
sumer
异常退出情况下数据也不会丢失
.
RabbitMQ
它没有用到超时机制
.RabbitMQ
仅仅通过
p>
Consumer
的连接中断来确认该
Me
ssage
并没有正确处理,
也就是说
RabbitMQ
给了
Consumer
足够长的时间做数据处
理。
如果忘记
ack,
< br>那么当
Consumer
退出时
,Mesage
会重新分发
,
然后
p>
RabbitMQ
会占用越来越多的内存
.
e
durability
消息持久化
要
持久化队列
queue
的持久化需要在声明时指定
durable=True;
这里要注意
,
队列的名字一定要是
Broker
中不存在的
,
不然不
能改变此队列的任何属性
.
队列和交换机有一个创建时候指定的标志
durable,durable
的唯一含义就是具有这个标志的队列和交换机会在
重启之
后重新建立
,
它不表示说在队列
中的消息会在重启后恢复
消息持久化包括
3
部分
1. exchange
p>
持久化
,
在声明时指定
durable => true
geDeclare(ExchangeName,
durable: true, autoDelete: false,
arguments: null);//
声明消
息队列,且为
可持久化的
1
持久化
,
在声明时指定
durable => true
eclare(QueueName, durable:
true,
exclusive: false, autoDelete:
false, arguments: null);//
声明
消息队列,且为可持久化的
1
3.
消
息持久化
,
在投递时指定
delive
ry_mode =>
2(1
是非持久
化
).
ublish(
-
-
-
-
-
-
-
-
-
上一篇:与战争有关的诗句_诗词(精华版)
下一篇:表示看的四字词语