消息队列概要

消息队列

协议

JMS

  • 代表:ActiveMQ

    • 消息模型

      • 点对点队列
      • 发布订阅
    • 消息格式

      • StreamMessage
      • MapMessage
      • TextMessage
      • BytesMessage
      • ObjectMessage

AMQP

  • 代表:RabbitMQ

    • 消息模型

      • direct exchange直连完全匹配
      • fanout exchange广播通知所绑定的
      • topic exchange可以模糊匹配
      • headers exchange
      • system exchange
    • 消息格式

      • Byte[]
    • 使用案例

      • 创建一个队列,创建一个交换器,定义一个路由

        • BindingBuilder.bind(demo01Queue()).to(demo01Exchange()).with(Demo01Message.ROUTING_KEY)
      • 生产者把消息放到队列

      • 消费者监听某个队列执行对应的Handler进行消费,使用注解@RabbitListener和@RabbitHandler

      • 路由规则

        • 通配符*和#的区别

          • 通配符 * ,代表一个占位符,或者说一个单词,比如路由为 user.*,那么 user.email 可以匹配,但是 user.aaa.email 就匹配不了
          • 通配符 # ,代表一个或多个占位符,或者说一个或多个单词,比如路由为 user.#,那么 user.email 可以匹配,user.aaa.email 也可以匹配
      • 批量

        • 发送
        • 消费
      • 消费与发送重试

        • 在消息消费失败的时候,Spring-AMQP 会通过消费重试机制,消费重试之后还失败进入死信队列
    • 定时消息

      • 死信队列 + TTL
      • Delayed Message Plugin插件,提供更加通用的定时消息的功能(推荐)
    • 消息模式

      • 集群消费

        • 配置多个消费实例,监听同一个Queue,自己的理解
      • 广播消费

        • 我的理解fanout模式
    • 并发消费

      • concurrency配置
    • 顺序消息

      • 做两件事

        • 保证 RabbitMQ Producer 发送相关联的消息发送到相同的 Queue 中

        • 有且仅启动一个 Consumer 消费该队列,保证 Consumer 严格顺序消费

        • 两个问题

          • 消息积压的问题

            • 将 Queue 拆成多个子 Queue
            • 将相关联的消息发送到相同的线程中来消费
          • 启动相同 Consumer 的多个进程

            • 引入 ZooKeeper 来协调,动态设置多个进程中的相同的 Consumer 的开关,保证有且仅有一个 Consumer 开启对同一个 Queue 的消费。
    • 重复消费

      • 消息生产时,MQ 内部针对每条生产者发送的消息生成一个 inner-msg-id ,作为去重和幂等的依据
      • 在消息消费时,要求消息体中必须要有一个 bizId(对于同一业务全局唯一,如支付 ID、订单 ID、帖子 ID 等)作为去重和幂等的依据,避免同一条消息被重复消费。
    • 事务消息

      • 开启 RabbitMQ 事务channel.txSelect
      • 发送消息
      • channel.txCommit/channel.txRollback(回滚或者提交事务)
    • 消息丢失

      • 生产者

        • 开启RabbitMq事务(同步,不推荐)
        • 开启Confirm模式(异步,推荐)
      • MQ

        • 开启RabbitMq持久化

          • 创建 queue 的时候将其设置为持久化
          • 发送消息的时候将消息的 deliveryMode 设置为 2
            就是将消息设置为持久化的,此时 RabbitMQ 就会将消息持久化到磁盘上去
      • 消费者

        • 关闭RabbitMq的自动ACK,改为手动ACK
    • 消息堆积问题

      • 队列上绑定多个消费者,提高消费速度

      • 给消费者开启线程池,提高消费速度

      • 使用惰性队列,可以再mq中保存更多消息

        • 惰性队列基于磁盘存储,消息上限高
        • 没有间歇性的page-out,性能比较稳定
    • 消息确认

      • 生产者

        • Confirm 模式

          • 同步
          • 异步
      • 消费者(Ack模式)

        • 自动确认
        • 手动确认
    • RPC 远程调用

    • MessageConverter

      • Java POJO 与AMQP Message 互转
    • 消费异常处理器

    • message 被可靠持久化的条件是 queue 和 exchange 具有 durable 属性,同时 message 具有 persistent 属性才行

    • 高可用

      • 单机模式

      • 普通集群模式

        • 会在集群的各个节点间共享部分数据,包括:交换机、队列元信息。不包含队列中的消息。
        • 当访问集群某节点时,如果队列不在该节点,会从数据所在节点传递到当前节点并返回
        • 队列所在节点宕机,队列中的消息就会丢失
      • 镜像集群模式(推荐)

        • 交换机、队列、队列中的消息会在各个mq的镜像节点之间同步备份。

        • 创建队列的节点被称为该队列的主节点,备份到的其它节点叫做该队列的镜像节点。

        • 一个队列的主节点可能是另一个队列的镜像节点
          所有操作都是主节点完成,然后同步给镜像节点
          主宕机后,镜像节点会替代成新的主

        • 三种模式

          • exactly(推荐)

            • count=镜像数量+1,count=2表示一个队列主和一个队列镜像,推荐count=N/2+1
          • all

            • 所有节点进行进行镜像
          • nodes

            • 指定队列创建到哪些节点,如果指定的节点全部不存在,则会出现异常
        • 仲裁队列,3.8以后才有的新功能,用来替代镜像队列,

          • 与镜像队列一样,都是主从模式,支持主从数据同步
            使用非常简单,没有复杂的配置
            主从同步基于Raft协议,强一致
    • Broker

      • 指一个或多个 erlang node 的逻辑分组,且 node 上运行着 RabbitMQ 应用程序
    • Cluster

      • 是在 Broker 的基础之上,增加了 node 之间共享元数据的约束
  • 主要分层

    • 功能层

      • 定义一系列命令
    • 传输层

      • 携带了从应用 → 服务端的方法,用于处理多路复用、分帧、编码、心跳、data-representation、错误处理。
  • 主要组件

    • exchange(交换器)

      • 从Publisher程序中收取消息,并把这些消息根据一些规则路由到消息队列(Message Queue)中
    • message queue(消息队列)

      • 存储消息。直到消息被安全的投递给了消费者
    • binding

      • 定义了 message queue 和 exchange 之间的关系,提供了消息路由的规则。

满足高性能

优势:异步、削峰、解耦(发布订阅模式)

劣势:可用性、复杂性、一致性

常见对比方向

吞吐量

  • (Rocket、Kafka)十万百万)>(Active、Rabbite)万

可用性

  • ActiveMQ 和 RabbitMQ主从架构
  • Rocket和Kafka基于分布式架构

时效性

  • Rabbite 微秒级 其他三个毫秒级

丢失性

  • ActiveMQ 和 RabbitMQ 丢失的可能性非常低, RocketMQ 和 Kafka 理论上不会丢失。

功能性

  • Kafka功能简单,其他三个功能较为完备

消息持久化

分布式KV存储

  • 这类 MQ 一般会采用诸如 LevelDB 、RocksDB 和 Redis 来作为消息持久化的方式

文件系统

  • 目前业界较为常用的几款产品(RocketMQ / Kafka / RabbitMQ)均采用的是消息刷盘至所部署虚拟机/物理机的文件系统来做持久化(刷盘一般可以分为异步刷盘和同步刷盘两种模式)

关系型数据库 DB

  • Apache下开源的另外一款MQ—ActiveMQ(默认采用的KahaDB做消息存储)可选用 JDBC 的方式来做消息持久化,通过简单的 XML 配置信息即可实现JDBC消息存储。

因此,综合上所述从存储效率来说,文件系统 > 分布式 KV 存储 > 关系型数据库 DB ,直接操作文件系统肯定是最快和最高效的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值