面试必备:对消息队列的理解?

llovebo

共 2901字,需浏览 6分钟

 ·

2021-07-02 01:29

简述:

消息队列,MessageQueue,简称MQ。消息队列中间件是分布式系统中重要的组件。

  消息(Message)是指在应用之间传送的数据,消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。
  消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,有消息系统来确保信息的可靠专递,消息发布者只管把消息发布到MQ中而不管谁来取,

  消息使用者只管从MQ中取消息而不管谁发布的,这样发布者和使用者都不用知道对方的存在。

架构模型:

c8842bcf0edb33b932ac5030cee7c4d6.webp

  • Producer:消息生产者,负责产生和发送消息到 Broker;

  • Broker:消息处理中心。负责消息存储、确认、重试等,一般其中会包含多个 queue;

  • Consumer:消息消费者,负责从 Broker 中获取消息,并进行相应处理;


详解:

我们在开发的过程中,会遇到像这样的情况:

  比如,我们需要开发一个给注册用户发送邮件的功能。其实制作起来并不是很难,无非就是两步,

    1、获取需要发送邮件的邮箱,并填写发送内容。

    2、发送。

这功能实现起来很简单,也很写,对吧!

那么,现在问题来了。

我现在有好百万的并发,几百万个用户同时都在注册(当然这里是假设)。这么高并发的情况下,我们还是用同步的方式去执行上面的1和2这两个步骤。

我可以很负责的告诉大家,一定会出现发送失败的案例,而且会很多。

那怎么解决这样的问题呢?

消息队列!!!

这里我们就引入了消息队列的概念。在理解这个概念之前,我们先来看一个生活中的小例子:

  我们都到餐厅去吃过饭对吧,服务员点单和厨师做菜,一定是服务员点单远远快于厨师做菜。那么问题再一次来了,如果服务员点单和厨师做菜是单线程的同步执行的。

  那么我们作为顾客,一定会有很大的怨言。因为我们要等到上一座点单的是的菜上齐过后才能点餐。

  但是在现实生活中,没有一家餐厅是这样的。通常餐厅中服务员点单和厨师做菜没有直接联系,服务员只管点单,点单成功后记录在一个介质上(这里假设为记录在纸上),然后传递给后厨,后厨再按照单子的前后顺序依次制作。

  其实,我们上面每天都经历的这个情形就是一个典型的消息队列:消息发布者(服务员),将消息存入消息队列(纸质点单记录),消息执行者(厨师)从消息队列取得消息并执行。

看了上面的例子,我相信绝大部分人对消息队列都应该有了一定的认识了。

下面为消息队列的一个抽象图。(生产者:服务员、消费者:厨师)

  4494ecc9fa756813528973457a9ace42.webp

下面,我们来讲一下如何使用消息队列实现百万并发的邮件发送(保证每一封邮件都能发送成功,除非客户填写了一个错误的邮件地址,这里我们不考虑这种情况)

需要注意的是,存储消息的介质有很多,我们可以根据需求随意选择,不用拘泥于redis的list。这里我们暂且选择mysql作为消息的存储介质。

我们新建一个表,用于存储消息。表明为MQ,含有三个字段id、u_email(用户邮箱)、post_content(发送内容)。

1、当用户申请注册的时候,将用户的邮箱和发送内容(发送内容可以视情况而定,这里的逻辑就具体问题具体分析了哈)存入MQ表,存入成功后马上就可以给用户反馈。比如(请到您的邮箱查看邮件是否已发送到您的邮箱......)

2、用php实现一个定时器,定时从MQ表中取出数据,进行邮件发送。如果成功则从数据表MQ中删除该条记录(当然,一般我们用逻辑删除),如果没有成功,则不删除。

优点:

1、后台运行,前台无需等待,马上可以给客户以反应,友好度较高。

2、成功率高,失败的记录会自动重发,直到成功。

在工作中会遇到很多刚接触消息队列的程序员,误以为redis的list就是消息队列。其实list只是redis的一种数据类型,它能够实现消息队列功能而已。

消息队列中间件有那些?

有Kafka、ActiveMQ、RabbitMQ、RocketMQ ?

他们的优缺点:

特性ActiveMQRabbitMQRocketMQKafka
单机吞吐量万级,比 RocketMQ、Kafka 低一个数量级同 ActiveMQ10 万级,支撑高吞吐10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响

topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topictopic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性ms 级微秒级,这是 RabbitMQ 的一大特点,延迟最低ms 级延迟在 ms 级以内
可用性高,基于主从架构实现高可用同 ActiveMQ非常高,分布式架构非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性有较低的概率丢失数据基本不丢经过参数优化配置,可以做到 0 丢失同 RocketMQ
功能支持MQ 领域的功能极其完备基于 erlang 开发,并发能力很强,性能极好,延时很低MQ 功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

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

一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了;

后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高;

不过现在确实越来越多的公司,会去用 RocketMQ,确实很不错(阿里出品),但社区可能有突然黄掉的风险,对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。

所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。

引用:https://www.cnblogs.com/wuzm/p/11105176.html

引用:https://www.cnblogs.com/573734817pc/p/10931632.html

支持小微:

腾讯云 搞活动了?玩服务器的可以搞搞。就这几天时间。

云服务器限时秒杀,1核2G 首年95元!

链接:https://curl.qcloud.com/RX2amrlR


右下角,您点一下在看图片c2cc46959b6ad5c9abf4bf202e62b220.webp

小微工资涨1毛

商务合作QQ:185601686





浏览 64
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报