01 | 为什么需要消息队列

文章目录

  • 讲解示例(秒杀系统)
  • 消息队列的试用场景
    • 异步处理
    • 流量控制
    • 服务解耦
  • 消息队列存在的问题

讲解示例(秒杀系统)

步骤

  • 风险控制
  • 库存锁定
  • 生成订单
  • 短信通知
  • 更新统计数据

流程

(APP)<=>(网关)<=>(风控)<=>(库存)<=>(生成订单)<=>(短信通知)<=>(更新统计数据)

核心问题
如何利用有限的服务器资源尽可能多地处理短时间海量请求

消息队列的试用场景

  • 异步处理
  • 流量控制
  • 服务解耦

异步处理

秒杀业务分析
对于秒杀系统而言,实际决定秒杀能否成功的步骤实际上只包含风控和库存两部分,因此在完成前两个动作之后就可以反馈给用户秒杀是否成功,后续三个操作可以在之后再去补偿处理。

异步流程

(APP)<=>(网关)<=>(风控)<=>(库存) =生产=> (消息队列)=消费=>(生成订单、短信通知、更新统计数据)

好处

  • 更快响应:可以更快的返回结果
  • 更好的性能:减少等待(秒杀业务不用等待非必要工作的结果),自然实现了步骤之间的并发,提升了系统总体的性能
  • 资源的有效利用:可以将大量服务器用于处理秒杀请求,在秒杀结束后将资源用于后续步骤

流量控制

系统分析
在部分工作实现异步处理之后,我们仍需考虑如何避免过多的请求压垮我们的秒杀系统,使系统能够实现自我保护。做到能够在海量请求之下,仍能够在自身能力范围内尽可能多的处理请求,拒绝处理不了的请求并且保证自身运行正常,实现一套健壮性的系统架构。

设计思路
使用消息队列隔离网关和后端服务,以达到流量控制和保护后端服务的能力

流程

(APP)<=>(网关) =生产=> (消息队列)=消费=>(秒杀服务)

优点

  • 架构健壮可靠:请求不会直接冲击后台服务,而是堆积在消息队列中,后端服务按照最大处理能力从队列中消费请求
  • 服务水平扩容方便:可随时增加秒杀服务的实例数量的方式提高后端处理能力
  • 削峰填谷:能够根据下游的处理能力自动调节流量,部分超出后端处理能力的峰值数据在请求低谷时进行处理(异步)

缺点

  • 响应变慢:增加了系统调用链环节,导致总体响应时延变长
  • 系统复杂度提高:上下游系统都要将同步调用改为异步消息,系统复杂度显著提高

替代方案(此处以令牌桶为例)

  • 原理:

令牌发生器以固定速率匀速生产令牌到令牌桶中,网关在将请求分发给服务之前必须先获取一个令牌,如果令牌桶中没有令牌,则拒绝请求

  • 优点

实现简单,只需在原本调用链的网关分发请求时增加一个获取令牌的逻辑即可 实现

  • 实现方式:
    • 固定容量的消息队列 + “令牌发生器”
    • redis计数器

服务解耦

场景分析
一个购物系统内部的可能操作:

  1. 在系统中的支付系统需要发起支付流程
  2. 风控系统需要审核会订单的合法性
  3. 客服系统需要给用户发短息告知用户
  4. 经营分析系统需要更新统计数据

这些业务的相关操作都需要获得订单数据的支持,而业务在实际场景中也是处于一个不断增密的过程中的,这就导致在一个高耦合的系统中订单服务需要根据不断变化、增长的下游服务去添加维护跟每一个服务的接口,并且还要在每一次维护后重新上线订单模块,这对于一个点上的核心业务来说,是不可接受的。

解决方案
维护一个规范的订单数据,当订单变化时发送一条遵守改规范的订单数据到消息队列的一个主题Order中,所有下游系统都订阅改主题Order,都可通过该队列获取到一份实时完整的订单数据

优点

  • 系统间耦合度降低
  • 维护方便:一个服务系统只需维护一个向下游分发的数据规范

消息队列存在的问题

  • 延迟问题
  • 增加了系统的复杂度
  • 可能产生数据不一致的问题

你可能感兴趣的:(消息队列,队列,分布式)