高并发-消息队列

2023-05-16

一、消息队列
消息队列在分布式系统中主要是为了解耦和削峰。

  1. 什么是消息队列
    我们可以把消息队列看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。
    在这里插入图片描述
    消息队列是分布式系统中重要的组件之一。使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。

我们知道队列 Queue 是一种先进先出的数据结构,所以消费消息时也是按照顺序来消费的。

  1. 为什么要用消息队列

    • 通过异步处理提高系统性能(减少响应所需时间)。
    • 削峰/限流
    • 降低系统耦合性

    2.1 通过异步处理提高系统性能(减少响应所需时间)
    在这里插入图片描述
    将用户的请求数据存储到消息队列之后就立即返回结果。随后,系统再对消息进行消费。

    因为用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败。因此,使用消息队列进行异步处理之后,需要适当修改业务流程进行配合,比如用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功,以免交易纠纷。这就类似我们平时手机订火车票和电影票。

    2.2 削峰/限流

    先将短时间高并发产生的事务消息存储在消息队列中,然后后端服务再慢慢根据自己的能力去消费这些消息,这样就避免直接把后端服务打垮掉。

    举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示:

    在这里插入图片描述
    2.3 降低系统耦合性

    使用消息队列还可以降低系统耦合性。我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。还是直接上图吧:
    在这里插入图片描述
    生产者(客户端)发送消息到消息队列中去,接受者(服务端)处理消息,需要消费的系统直接去消息队列取消息进行消费即可而不需要和其他系统有耦合,这显然也提高了系统的扩展性。

    消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。 从上图可以看到消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计。

    消息接受者对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列流程。

    另外,为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。

    备注: 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的。除了发布-订阅模式,还有点对点订阅模式(一个消息只有一个消费者),我们比较常用的是发布-订阅模式。另外,这两种消息模型是 JMS 提供的,AMQP 协议还提供了 5 种消息模型。

  2. 使用消息队列带来的一些问题

系统可用性降低: 系统可用性在某种程度上降低,为什么这样说呢?在加入 MQ 之前,你不用考虑消息丢失或者说 MQ 挂掉等等的情况,但是,引入 MQ 之后你就需要去考虑了!

系统复杂性提高: 加入 MQ 之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题!

一致性问题: 我上面讲了消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了!

  1. JMS VS AMQP

    4.1 JMS

    JMS(JAVA Message Service,java 消息服务)是 java 的消息服务,JMS 的客户端之间可以通过 JMS 服务进行异步的消息传输。JMS(JAVA Message Service,Java 消息服务)API 是一个消息服务的标准或者说是规范,允许应用程序组件基于 JavaEE 平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。

    ActiveMQ 就是基于 JMS 规范实现的。

    JMS 两种消息模型

    ① 点到点(P2P)模型
    在这里插入图片描述
    使用队列(Queue)作为消息通信载体;满足生产者与消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。比如:我们生产者发送 100 条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半(也就是你一个我一个的消费。)

    ② 发布/订阅(Pub/Sub)模型
    在这里插入图片描述
    发布订阅模型(Pub/Sub) 使用主题(Topic)作为消息通信载体,类似于广播模式;发布者发布一条消息,该消息通过主题传递给所有的订阅者,在一条消息广播之后才订阅的用户则是收不到该条消息的。

    JMS 五种不同的消息正文格式
    JMS 定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。

    StreamMessage – Java 原始值的数据流
    MapMessage–一套名称-值对
    TextMessage–一个字符串对象
    ObjectMessage–一个序列化的 Java 对象
    BytesMessage–一个字节的数据流

    4.2 AMQP
    AMQP,即 Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准 高级消息队列协议(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。

    RabbitMQ 就是基于 AMQP 协议实现的。

    4.3 JMS vs AMQP
    在这里插入图片描述
    总结:

    AMQP 为消息定义了线路层(wire-level protocol)的协议,而 JMS 所定义的是 API 规范。在 Java 体系中,多个 client 均可以通过 JMS 进行交互,不需要应用修改代码,但是其对跨平台的支持较差。而 AMQP 天然具有跨平台、跨语言特性。

    JMS 支持 TextMessage、MapMessage 等复杂的消息类型;而 AMQP 仅支持 byte[] 消息类型(复杂的类型可序列化后发送)。

    由于 Exchange 提供的路由算法,AMQP 可以提供多样化的路由方式来传递消息到消息队列,而 JMS 仅支持 队列 和 主题/订阅 方式两种。

  2. 常见的消息队列对比
    在这里插入图片描述
    总结:

    ActiveMQ 的社区算是比较成熟,但是较目前来说,ActiveMQ 的性能比较差,而且版本迭代很慢,不推荐使用。

    RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 和 RocketMQ ,但是由于它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。但是也因为 RabbitMQ 基于 erlang 开发,所以国内很少有公司有实力做 erlang 源码级别的研究和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这四种消息队列中,RabbitMQ 一定是你的首选。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。

    RocketMQ 阿里出品,Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的 MQ,并且 RocketMQ 有阿里巴巴的实际业务场景的实战考验。RocketMQ 社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准 JMS 规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用 RocketMQ 挺好的

    Kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

高并发-消息队列 的相关文章

  • Docker安装Kafka消息队列

    文章目录 1 安装zookeeper2 安装kafka3 安装kafka map xff08 可选 xff09 1 安装zookeeper span class token function docker span run span cla
  • UC/OS-III 消息队列

    消息队列 一 消息队列基本概念讲解1 消息队列基本概念2 消息池2 1 消息池概念2 2 消息池初始化2 3 消息队列的运作机制2 4 消息队列的阻塞机制2 5 消息队列的应用场景 二 消息队列创建步骤1 定义消息队列2 创建消息队列 三
  • RabbitMQ(四)消息Ack确认机制

    RabbitMQ 四 消息Ack确认机制 确认种类 RabbitMQ的消息确认有两种 消息发送确认 这种是用来确认生产者将消息发送给交换器 交换器传递给队列的过程中 消息是否成功投递 发送确认分为两步 一是确认是否到达交换器 二是确认是否到
  • Springboot整合RabbitMQ

    一 Springboot整合RabbitMQ的代码实现 1 引入Springboot整合RabbitMQ的依赖
  • RocketMQ和kafka

    RocketMQ 分为集群消息 一组中只有一个消费者竞争到消息 和广播消息 组内消费者都会消费消息 相关概念有 topic 一个消息的主题 一级分类 tag 消息的二级分类 queque 消息队列 brocker里直接存储消息就是在queq
  • RocketMQ中文文档(译)

    前言 近日需要研究一下RocketMQ 为了方便日后查找 因此对官方英文文档进行翻译记载 也希望能帮助到要学习的朋友 阅读后发现 文档还是比较粗略的 大概也只能了解些概念和简单实用 快速入门部分比较简单 因此暂时没翻译只翻译其中重要的几个部
  • RocketMQ系列之入门

    前言 之前我们把RMQ的多Master集群搭建起来了 我们今天就来看看如何向这个集群生产消息以及消费消息 集群搭建回顾 回顾上节的内容 我总结下以下几步 第一 最新版RMQ4 2 0要求最低JDK8版本 第二 修改虚拟机的host 配置na
  • kafka(一)kafka的基础与常用配置

    文章目录 一 kafka基础内容 二 kafka 中重要的参数配置 2 1 log dirs 2 2 unclean leader election enable 2 3 message max bytes 2 4 request requ
  • 消息队列MQ-面试题

    目录 1 什么是消息队列 2 为什么要使用消息队列 1 解耦 2 异步处理 3 削峰 3 使用消息队列带来的一些问题 4 JMS两种消息模型 5 消息队列由哪些角色组成 6 常见消息中间件比较 7 如何保证消息队列是高可用的 RocketM
  • 通过Java操作Kafka

    通过Java操作Kafka 前置知识 https editor csdn net md articleId 125883056 创建maven项目 导入kafka客户端依赖
  • (二)Rocketmq目录结构及设计目标

    文章目录 一 目录结构 二 设计理念与目标 2 1设计理念 2 2设计目标 一 目录结构 1 broker broker模块 2 client 消息客户端 包含消息生产者 消费者相关类 3 common 公共包 4 dev 开发者信息 非源
  • RabbitMQ中的限流、return机制、死信队列

    目录 优点 缺点 1 限流 2 return机制 3 死信队列 优点 高可用性 RabbitMQ支持集群和镜像队列等多种方式实现高可用性 保证系统稳定运行 可靠性强 RabbitMQ使用AMQP协议作为消息传递的标准 能够确保消息传递的可靠
  • RocketMQ第五篇 RocketMQ API基本使用

    目录 生产者Product 消费者Consumer 前面已经学习了Rocket的基本知识 以及搭建MQ单机版和集群环境 下面开始进行实际开发 根据前面下载的RocketMQ源码 开展讲解RocketMQ 的基本使用 生产者Product 在
  • 代码技巧——如何关闭订单?延迟任务的实现方案【建议收藏】

    先思考个问题 为什么要关闭订单 业务上 1 提供待付款时间 而不是简单的 一次付款机会 提高业务指标之一的成单率 成单率 成功下单的人数 发起支付的人数 2 下单成功意味着这个商品被当前订单占用 库存已经预扣减 如果迟迟不支付则需要回收库存
  • Kafka实战——简单易懂的生产者消费者demo

    单线程版本适合本地调试 多线程版本适合做压测 1 引入maven依赖
  • RocketMQ 简介

    本文根据阿里云 RocketMQ产品文档整理 地址 https help aliyun com document detail 29532 html userCode qtldtin2 简介 RocketMQ是由阿里捐赠给Apache的一款
  • 消息队列:Ubuntu16.04安装和Web页面管理RabbitMQ(楼主亲测、真实有效)

    RabbitMQ 总来来说 RabbitMQ的安装还是有一些难度的 不同的方式 安装的方法也是完全不一样 还要解决蛮多依赖 加上现在有些网站 极其不负责 很多博文都没有经过测试检验就直接发出来的 楼主来亲测一下 希望能对大家有好的帮助 一
  • docker安装rocketmq4.6.1(精简版)

    一 创建文件 mkdir p usr local rocketmq server logs usr local rocketmq server store usr local rocketmq broker logs usr local r
  • RT-Thread记录(七、IPC机制之邮箱、消息队列)

    讲完了线程同步的机制 我们要开始线程通讯的学习 线程通讯中的邮箱消息队列也属于 RT Thread 的IPC机制 目录 前言 一 邮箱 1 1 邮箱控制块 1 2 邮箱操作 1 2 1 创建和删除 1 2 2 初始化和脱离 1 2 3 发送
  • 腾讯技术工程总结-主流消息队列你了解哪些?

    文章参考 腾讯技术工程 关于消息队列的知识总结 主流消息队列你了解哪些 消息队列的发展历程 2003 年至今有很多优秀的消息队列诞生 如 kafka 阿里自研的 rocketmq 以及后起之秀 pulsar 消息队列在刚出现所需要解决的问题

随机推荐

  • CAN2.0B 数据帧详解

    CAN的帧类型分为数据帧 遥控帧 错误帧 过载帧以及帧间空隙 xff0c 本文将对数据帧的帧结构展开说明 xff1a 引言 xff1a CAN2 0协议分为A版本和B版本 xff0c A版本协议为11位标识符 xff08 标准帧 xff09
  • window下c/c++异步发送udp和非阻塞的方式接收udp的类封装

    以下代码对udp发送和接收都做了封装 xff0c 在发送和接收前都需要去注册使用的功能 xff0c 从而做到需要哪个模块才启动哪个模块的功能 xff0c 避免资源的浪费 udp发送功能 使用列表和信号量的方式实现异步发送数据 xff0c 避
  • c/c++使用libhdfs对HDFS(Hadoop分布式文件系统)进行读写操作

    最近需要对HDFS进行读写操作 xff0c 参考hdfs h头文件里面的注解 xff0c 编写了一个例子 详细的说明在代码的注释中 如发现问题欢迎批评指正 span class token macro property span class
  • 使用c/c++将十六进制的stl字符串转换成IEEE - 754 浮点数

    span class token keyword typedef span span class token keyword union span span class token punctuation span span class t
  • 使用 C++ 处理 JSON 数据交换格式

    使用 C 43 43 处理 JSON 数据交换格式 一 摘要 JSON 的全称为 xff1a JavaScript Object Notation xff0c 顾名思义 xff0c JSON 是用于标记 Javascript 对象的 xff
  • C++ -- 智能指针( C++11与boost库的智能指针及其使用)

    1 智能指针的引入 1 在动态内存管理中 xff0c 如果new上一块空间 xff0c 但是没有delete xff0c 就会产生内存泄露的问题 2 但是有时候 xff0c 我们new了 xff0c 也delete了 xff0c 但是还会出
  • 动态库与静态库区别

    首先 xff0c 两者最重要的区别在于该库是否被编译进目标程序当中 静态库 xff1a 该库在编译的时候会直接整合到目标程序当中 xff0c 也就是说 xff0c 每个程序的静态库都是独立的 这样使得文件比较大 而且因为是编译的的时候整合进
  • 解决ubuntu20.04虚拟机无法上网的问题

    64 linux虚拟机无法正常上网 前言 刚建立好的linux虚拟机使用NAT方式可以连接外网 xff0c 系统重启几次 xff0c 系统无法上网 xff0c 这是什么问题导致的呢 xff1f 提示 xff1a 以下是本篇文章正文内容 xf
  • Arduino系列教程之 – PWM的秘密

    转载地址 xff1a http www diy robots com p 61 814 感谢作者的翻译 PWM是啥玩意儿 xff1f PWM是 怕玩命 的缩写 xff0c 英文写法是 Pulse width modulation xff0c
  • YOLOv2代码分析_读取labels[by zhangzexuan]

    YOLOv2代码分析 读取labels by zhangzexuan YOLOv2代码分析 读取labelsby zhangzexuan YOLOv2的输入代码阅读 嗯 现在参与的项目要求在人脸检测步骤直接连同人脸特征点一起预测出来 xff
  • 【企业微信】获取token & 发送应用消息

    企业微信获取token 存入redis 设置时长2小时 amp amp 发送企业应用消息接口 1 常量类 span class token keyword package span span class token namespace co
  • 学习笔记--HTTP-字段总结(一)-与传输实体相关的报文字段总结

    目录 一 概述 二 介绍一些常用字段 三 传输实体的一些属性 1 传输的数据类型 2 实体的语言类型和编码 3 编码类型 四 文件类型和压缩编码字段 1 Accept 2 Content Type 3 Accept Encoding 4 C
  • C/C++ 去掉宏定义__FILE__路径

    一 问题 在日志模块中往往带着文件信息 xff0c 有的源文件是加载其他路径下的源文件 xff0c 但是不想让别人看到文件路径信息 xff0c 只显示源文件的名字和行数即可 如下图所示 xff0c 有烦人的相对路径 二 解决方案 自定义一个
  • C语言提高(一)

    C语言提高 CS和BS的区别函数封装和数组形参退化为指针数据类型本质变量的本质内存分区模型全局区以文字常量区为例分析全局区 栈区堆区 函数的调用模型函数调用变量传递分析静态局部变量的使用栈地址的生长方向堆地址的生长方向内存的存放方向 以数组
  • ROS Gazebo(三):启动gazebo/URDF

    打开Gazebo的方式主要有两种 xff1a rosrun 和 roslaunch 1 启动ROS节点 启动ROS节点 bring up 机器人的标准工具是roslaunch 打开一个空的Gazebo世界命令如下 xff1a roslaun
  • Windows与Ubuntu之间通过网线传输文件

    一 windows与Ubuntu之间网线直连搭建局域网 把网线连好后 xff0c 在两个系统中做以下设置 Windows下的配置 右键右下角的网络图标 xff08 或者右键网络 属性 xff09 更改适配器设置 以太网 右键属性 TCP I
  • Jetson TX2——CAN口的使用

    Jetson TX2 之CAN口的使用 TX2上有2个CAN控制器 xff0c CAN控制器需要通过CAN收发器连接到物理总线上 具体参阅原理图和相关技术参考手册 下载地址 xff1a https developer nvidia com
  • Jetson TX2——串口的使用(TTL-RS485)

    Jetson TX2之串口的使用 xff08 TTL RS485 xff09 TX2串口设备 TX2 有5个 UARTs 到主连接器 其中UART3 用于 WLAN BT 有关 UARTs 的典型任务 请参见下表 查看可用串口设备 xff1
  • 面试题知识点全纪录---容器

    注意 xff1a 该博客仅是本人对掌握知识的测试 xff0c 具体内容请移步guide哥网站 xff01 xff01 xff01 https snailclimb gitee io javaguide 链接 JAVA集合框架 https w
  • 高并发-消息队列

    一 消息队列 消息队列在分布式系统中主要是为了解耦和削峰 什么是消息队列 我们可以把消息队列看作是一个存放消息的容器 xff0c 当我们需要使用消息的时候 xff0c 直接从容器中取出消息供自己使用即可 消息队列是分布式系统中重要的组件之一