热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

消息队列:基础概念篇

前言接下来我在写一些技术类科普的文章,大致会以who(它是谁)、why(为什么)、how(怎么做)的写作方向来向大家介绍说明,因为我认为这样子介绍说明思路会比较明确,也能够更快学会




前言

接下来我在写一些技术类科普的文章,大致会以who(它是谁)、why(为什么)、how(怎么做)的写作方向来向大家介绍说明,因为我认为这样子介绍说明思路会比较明确,也能够更快学会一项新技能,个人拙见,写得不好、不对的地方,还望大家赐教。


Who|什么是消息队列(MQ)

在计算机科学中,消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的资料,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它。[1]

一个 WIMP 环境像是 Microsoft Windows,借由优先的某些形式(通常是事件的时间或是重要性的顺序)来存储用户产生的事件到一个 事件贮列 中。系统把每个事件从事件贮列中传递给目标的应用程序。

​ —维基百科



MQ(Message Queue)消息队列,是基础数据结构中“先进先出”的一种数据结构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。

​ —百度百科


简单来说,就是排队的意思,先进先出。


Why|为什么用MQ

查个题外话,我认为使用一项新技术的时候,我们要综合考虑该技术的利弊性、维护性、成本性,而不是盲目跟随主流,自己的业务产品不管三七二十一都使用最新的技术,也得根据项目的实际情况来最终决定。

回归主题,存在即合理,它的主要的三大应用场景:应用解耦、异步消息、流量削峰,除此之外,还有延迟通知、分布式事务、顺序消息、流式处理等等。下面我主要细说下它的三大应用场景。


应用解耦


一个业务需要多个模块共同实现,或者一条消息有多个系统需要对应处理,只需要主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合。


举个例子,有个业务场景,我有三个系统,分别是A、B、C系统,大致业务是,A系统操作完具体业务,会分别调用B跟C的接口。

传统做法


正常情况,我们会直接在A系统的代码里面写上对B、C系统的接口请求。如下图


在这里插入图片描述

可能存在问题:


1、假设其中一个系统因为不确定因素导致宕机了,这时候是不是整个业务都走不下去了

2、假设业务突然又需要增加调用一个D系统,或者去除C系统的调用,那是不是代码又要重新改一次

3、改任何一个系统的代码,都要小心翼翼的


因此根据以上几点,我们可以明显看出应用系统之间的耦合度很高,没有很独立的思想,所以就需要引用MQ来作为中间件来降低它们之间的耦合度。

MQ做法


A系统就产生一条数据发送到MQ,这时候BCD系统哪个需要这个数据就自行去消费即可,如果又新增或减少好几个应用系统,只需要在去消费或者取消消费。


在这里插入图片描述

由此可见,这样子A系统是不是很独立了,压根就不需要管BCD系统会出现什么异常情况,A系统的代码也不再需要重新维护。


异步处理


主业务执行结束后从属业务通过MQ,异步执行,减低业务的响应时间,提高用户体验。


举个例子,有个预约挂号的业务,病人挂号成功后,需要发送短信通知跟微信通知

传统做法


假设都正常执行,用户挂号操作调用挂号系统接口耗时200ms,然后在调用短信接口200ms,再调用微信通知接口200ms,那这样子加起来一共就要600ms,这是正常情况,假如出现某个接口很耗时,那这样子就很影响用户体验了


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AfpiJsvW-1642755230477)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220121144534818.png)]

MQ做法


挂号系统接口是必须的,还是200ms,然后挂号系统在产生消息到MQ花费3ms,短信接口跟微信系统到时候在自行消费,那响应速度一下子变成快了近2倍


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-44PXNAi3-1642755230481)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220121152801920.png)]


流量削峰


高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪。


举个例子,A系统每天都风平浪静的,每秒平均的并发量也才50个,但是有一天,在某个时间段,突然每秒的并发请求量激增到6K+,假如该系统的数据库是用mysql,每秒执行6K+条的SQL。正常的mysql数据库能够抗住每秒2k条的执行语句,一下子到6k+,会直接导致数据库崩溃,从而导致系统也崩溃了。

传统做法

在这里插入图片描述

MQ做法


引用 MQ,直接将全部的请求(每秒 6k+) 个请求写入 MQ,因为我们的A系统最大的承载量是每秒2k个请求,所以每次从MQ中慢慢拉取,一次就拉取2k请求,不超过自己系统的最大请求量就行了。这样子,即使在高峰的请求量,也不用在怕A系统会崩溃。虽然在高峰期的时候,这些请求可能堆积在MQ中有几十万甚至几百万条,但是只要一过高峰期,从MQ每秒2k条的拉取执行,很快也会被消化完毕的。


在这里插入图片描述


MQ有什么优缺点

东西都是有两面性的。优点就不用说了吧,就是上面说的那些,下面我们来说说有哪些缺点跟需要考虑的问题


  • 系统可⽤性降低

系统引⼊的外部依赖越多,越容易挂掉。本来 A 系统调⽤ BCD 三个系统的接⼝就好了,没啥问题,但偏偏加个 MQ 进来,万⼀ MQ 挂了咋整,MQ ⼀挂,不仅整套系统崩溃的,你也就崩溃?所以要保证消息队列的⾼可⽤


  • 系统复杂度提⾼

硬⽣⽣加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性?


  • ⼀致性问题

A 系统处理完了直接返回成功了,都以为这个请求就成功了;但是问题是,要是 BCD三个系统中,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?这时候数据就不⼀致了。

总结一下:


  • 如何保证消息的高可用

  • 如何保证消息消费的幂等性

  • 如何处理消息丢失问题

  • 如何保证消息的顺序性

  • 如何解决消息积压

  • 如何保持数据一致性


How|怎么用MQ

目前市场常见的消息队列产品主要有ActiveMQ、RabbitMQ、RocketMQ、Kafka等。

那么怎么选择一款符合自己产品的MQ就很关键了。下面有个对比分享做参考。


特性ActiveMQRabbitMQRocketMQKafka
开发语言JavaErlangJavaScala&Java
客户端支持语言Java、C、C++、Python、PHP、Pert、.net等几乎支持所有常用语言Java、C++官方支持Java,但是开源社区有常用语言版本
单机吞吐量万级,比 RocketMQ、Kafka 低一个数量级同 ActiveMQ10 万级,支撑高吞吐10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topictopic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性ms 级微秒级,这是 RabbitMQ 的一大特点,延迟最低ms 级延迟在 ms 级以内
可用性高,基于主从架构实现高可用同 ActiveMQ非常高,分布式架构非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性有较低的概率丢失数据基本不丢经过参数优化配置,可以做到 0 丢失同 RocketMQ
功能支持MQ 领域的功能极其完备基于 erlang 开发,并发能力很强,性能极好,延时很低MQ 功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

综上,各种对比之后,有如下建议:


  • ActiveMQ最为老牌MQ,现在用的人不多,社区也不太活跃,所有不推荐
  • 中小企业,并发量不是很大的,追求稳定,RabbitMQ是首选
  • Java首选RocketMQ,毕竟阿里出品,向大厂看齐
  • 大数据领域的用 Kafka 是业内标准的,社区活跃度很高


推荐阅读
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • ElasticSerach初探第一篇认识ES+环境搭建+简单MySQL数据同步+SpringBoot整合ES
    一、认识ElasticSearch是一个基于Lucene的开源搜索引擎,通过简单的RESTfulAPI来隐藏Lucene的复杂性。全文搜索,分析系统&# ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 先看一段错误日志:###Errorqueryingdatabase.Cause:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransie ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 本文介绍了SPOJ2829题目的解法及优化方法。题目要求找出满足一定条件的数列,并对结果取模。文章详细解释了解题思路和算法实现,并提出了使用FMT优化的方法。最后,对于第三个限制条件,作者给出了处理方法。文章最后给出了代码实现。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
author-avatar
仲颖凯翰奕颖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有