美文网首页java架构设计专题
谈谈消息队列的设计与实现

谈谈消息队列的设计与实现

作者: 先生zeng | 来源:发表于2019-10-18 17:32 被阅读0次

定义

消息队列技术是分布式应用间交换信息的一种技术。

  • 消息队列可以驻留在内存或磁盘上,队列存储消息直到它们被应用程序取走。
  • 通过消息队列,应用程序可独立地执行,不需要直到彼此地位置或在继续执行前不需要等待接收程序接收此消息。

应用场景

  • 异步通信

  • 解耦业务

      基于消息解耦,关注“通知”,而非关注“处理” 
    
  • 错缝与流量控制

  • 广播

  • 时序保证

如图:

image

上图中,搜索时,需要去跟商品还有后台交互,交易时,也需要跟后台交互商品交互。四个模块之间地关联错综复杂,这时候可以借助消息队列去处理。

消息队列模型

  • 广播模式
image
  • P2P点对点
image

模块构成

  • Broker: 消息服务器
  • Producer: 消息生产者,业务地发起方,负责生产消息传递给Broker
  • Consumer: 消息消费者,业务地处理方,负责从broker获取消息并进行业务逻辑处理
  • Topic: 主题,发布订阅模式下的消息统一汇集地,不同生产者向Topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的广播。
  • queue: 队列,P2P模式下,特定生产者向特定Queue发送消息,消费者订阅特定的queue完成指定消息的接收。
  • Message: 消息体,根据不同业务通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输。

传统通信协议

  • AMQP协议: 应用协议的一个开放标准,为面向消息的中间件设计
  • MQTT协议: 格式简洁、占用带宽小,移动端通信,PUSH、嵌入式通信系统,基于TCP的二进制协议。
  • STOMP: 简单文本消息协议。
  • XMPP协议: 基于XML的协议。
  • 自定义协议: ZeroMQ/Redis/KafKa/RocketMQ协议自定义二进制协议。
  • 基于TCP/IP Socket接口进行传输。

设计考虑点

从关注处理到关注通知


image

高级特性如下:

可靠投递

消费确认

重复消息和顺序消息

性能考虑

PUSH 或 PULL

业界产品

  1. RebbitMQ
image
  1. ZeroMQ
image
  1. Apache ActiveMQ
image
  1. Kafka
image
  1. Apache RocketMQ
image

6.NSQ (了解)

image
  1. beanstalkd(了解)
image

应用环境推荐

生产环境推荐

  • 高吞吐量、高可靠性可容忍场景的

    • 日志处理
      • kafka
  • 高可靠场景

    • 电商订单服务
      • RocketMQ

存储模型的区别

RocketMQ存储模型

image

顺序写,随机读。

  • 所有数据单独存储在一个commitLog里面,跟mysql中的binlog一样,安全顺序写,随机读。
  • 对最终用户展现的队列实际只存储消息在commitLog的位置信息,并且串行方式刷盘。
    • 好处
      • 队列轻量化,单个队列数据流非常少。
      • 对磁盘的访问串行化,避免磁盘竞争。
    • 缺点
      • 写顺序写,但是读变成完全随机读。
      • 读一条消息,先读Consume Queue,在读Commit Log,增加了读开销。
      • 要保证Commit Log与Consume Queue 完全一致,增加了架构设计的复杂性。

RocketMQ刷盘策略

支持异步刷盘

    写完PageCache直接返回。
    RocketMQ可配置。
image

写完内存就返回,异步的去刷新Disk。

支持同步刷盘

  • 写入PageCache,线程等待,通知刷盘程序刷盘。
  • 刷盘线程刷盘后,唤醒前端等待线程,
  • 可能是一批线程。
  • 前端等待线程向用户返回成功。

RocketMQ实现高可用

  • 对于非实时性消息
    • 对各Master-Slave对。
    • Pub多个Master
    • Sub多个slave
  • 对于严格时序消息
    • 单机单线程。
    • Master-slave 如果master挂了,会发送失败,同时也不能消费。
    • 这时候高可用如何保证???

设计方案

  • 目前nameServer是无状态的,Broker的心跳信息上报给nameServer。
  • 引入zookeeper,NameServer通过Zookeeper(nameServer A)竞争称为Controller
  • Broker依赖Zookeeper,通过Zookeeper获取Controller所在的nameServer。
  • Broker的心跳信息只上报给Controller,再由nameServer复制给其他nameServer
    nameServer地位变成不对等,有Master的概念。
    切换过程中,通过Controller来切换slave变成Master,同时更新其他两个nameServer的路由信息。
  • NameServer Controller的HA由ZK来负责
  • Client任然是任意连接一台nameServer。
image

RocketMQ 消息可靠性。

  • ACK
    • RocketMQ Producer 重试三次
    • Consumer失败,可以异步再消费,可以回溯。
    • 消费Offset可以保存本地,或者保存到Broker
  • 网络
    • netty

推拉

  • 消费端采用推方式还是拉方式消费消息
    • PULL OR PUSH
      • Long Pulling

相关文章

  • 谈谈消息队列的设计与实现

    定义 消息队列技术是分布式应用间交换信息的一种技术。 消息队列可以驻留在内存或磁盘上,队列存储消息直到它们被应用程...

  • springboot项目架构(4)activemq、rabbit

    消息队列实现 支持的消息队列 ActiveMq RabbitMq RocketMq Kafka 各个队列实现队列与...

  • Redis作为消息队列与RabbitMQ的比较

    Redis作为消息队列与RabbitMQ的比较 RabbitMQ RabbitMQ是实现AMQP(高级消息队列协议...

  • 消息中间件

    消息中间件,也可以叫做中央消息队列或者是消息队列(区别于本地消息队列,本地消息队列指的是 JVM 内实现的队列实现...

  • Kafka_核心

    kafka集群 Kafka的设计都是为了实现kafak消息队列消费数据的语义Kafka消息队列中数据消费的三种语义...

  • redis消息队列的四种实现方式之List的简单队列和延时队列

    目录 《redis消息队列的四种实现方式之List的简单队列和延时队列》(本篇) 《redis消息队列的四种实现方...

  • 消息队列介绍与设计

    “ 消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列...

  • 卡顿优化(下)

    1. 消息队列 基于消息队列实现,通过替换 Looper 的 Printer 实现。 问题:线上开启这个监控模块,...

  • 简单易用的消息队列框架的设计与实现

    本文欢迎转载,转载请注明原文链接,并附作者个人信息李艳鹏。 1 背景介绍 消息队列在互联网领域里得到了广泛的应用,...

  • 消息队列设计

    消息队列通常作为企业IT系统内部通信的核心手段具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异...

网友评论

    本文标题:谈谈消息队列的设计与实现

    本文链接:https://www.haomeiwen.com/subject/ldqwmctx.html