Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

异步处理——Queue

  • 异步处理 Asynchronous

    • 将耗时的同步任务 改成 异步处理,可单独建立排队机制,慢慢取出并外包给多个worker去计算,实现扩展性,就叫 asynchronous
    • 通过 消息队列 Queue 这种结构实现
  • 好处

    • 系统间解耦,主任务 不必依赖于 其他任务 同步完成
    • 其他任务通过队列外包给worker延后处理,使得系统对用户的响应时间下降,吞吐量提升
    • 可以进一步实现并行
  • 漏斗模型

    • 消息队列就像一个漏斗,用来控制流量和流速
      • 汹涌而至的消息,从敞口流入,经过缩口,以固定速率输出给消费者
    • 如果生产速率始终大于消费速率,就会在漏斗中累积,最终溢出,导致消息丢失
      • 这种现象称为 Back pressure(反向压力)
      • 此时可以限制队列大小,排满了就返回503,让生产者稍后重试
    • 所以只有生产速率只是短期大于消费速率的情况下,漏斗才有意义,形成流量削峰的效果
  • 常用的消息队列组件

    • RabbitMQ
      • 使用比较多,一直在更新优化,github关注10K
      • Erlang语言开发的
      • 主要用于对时延敏感的在线业务场景,可利用丰富的消息类型支持多变的业务
    • RocketMQ
      • 阿里开源的,可以使用云服务,github关注17K,已入驻Apache
      • java语言开发的,阅读源码方便
    • Kafka
      • github关注22K
      • Scala语言开发,阅读也比较方便
      • 主要用于可接受一定时延的日志收集或者业务数据埋点上报,可利用批处理提高吞吐量,做到单机10万级以上
    • ActiveMQ(不建议)
      • 比较老,不活跃
      • java语言开发的
  • 三个角色

    • 生产者
      • 对外的应用程序,往队列里发布任务,并告知用户其状态
    • 消费者
      • 工作的worker,拿到任务执行,完成后通知
    • Broker
      • 从队列中取出并分发任务,保证任务的完整性,包括失败重试,动态调整分发策略
  • 两种模式

    • 推模式
      • Broker收到消息后,通过长连接通道主动推送给Consumer
      • 优点
        • 实时性强
        • 客户端实现简单,只需要监听就行
      • 缺点
        • 容易导致客户端消息堆积,无法自主可控
        • 服务端逻辑变得复杂,需要优化推送策略,考虑不同客户端的消费能力去分发
    • 拉模式
      • Consumer主动向Broker索要消息
      • 不能用定时拉取,时长不好控制
      • 可以采用长轮询
        • 客户端发起索要请求
          • 如果服务端有数据就直接返回
          • 如果没数据,就保持连接一定时间,这段时间如果有数据就接收
          • 超时后,重新发起索要请求
      • 优点
        • 不会出现消息堆积,自主可控
        • 长轮询的实时性也可以保证
        • 服务端逻辑简化
      • 缺点
        • 客户端实现复杂
  • 如何设计一个消息队列

    • 需要服务端,主要角色是消息的接收者,即Broker

      • 1、消息写入磁盘持久化,防止消息丢失
        • 设计存储格式
        • 设计提交日志和检查点
      • 2、考虑主从设计
        • 主节点数据同步给从节点,出问题后从节点顶上
        • 同时从节点可提供读操作
      • 3、考虑分片到多台机器
        • 一个Topic数据分成多份,存储在不同的Broker上
          • 需要考虑不同Topic的使用量级,均匀分配
          • RocketMQ实现是 一个Topic下的消息会存储到多个Queue中(不是固定的),并记录这个一对多的关系
        • 需要注册中心协调这些分片
          • 哪些分片存了这个Topic?——存储信息
          • 哪些Broker在线?——心跳检查
          • 为防止单节点故障,需要多个注册中心,都要存储一份这些信息
            • RocketMQ实现是 Broker启动时轮流向所有注册中心注册
            • Eureka实现是 Broker启动时只注册一个,然后立马返回,后面注册中心之间再同步
            • Zookeeper实现是 Broker启动时只注册一个,然后等注册中心之间全部或半数同步完,再返回
    • 需要客户端,提供集成的SDK

      • 1、封装一套 发送消息 和 消费消息 的方法
        • 统一接口,解耦
      • 2、跟服务端Broker通信
        • 网络通信可以选Netty框架,也可以直接用http
      • 3、兼容多种项目
        • 支持多语言
    • 后台管理功能

      • 查看集群状态
      • 消息状态查询、消费轨迹查询
      • 总的消费数量统计