消息队列详解与应用

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 消息队列详解与应用

一 、 概 念


首先问什么是消息?

“消息”是在两台计算机间传送的数据单位; 其中消息可以为数字、字符、或者一串字符、实体对象。

什么是队列?
队列:在数据结构中的特点为先进先出,可以理解为生活中的排队形式。

什么是消息队列?
但从名字中可以看出,为存放消息的一种队列
可以简单理解为:把要传输的数据放在队列中。而消息队列是分布式系统中重要的组件,可以在 分布式环境 下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步

对于消息队列来说,我们一般会简称它为MQ,主要的就是解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。把数据放到消息队列叫做生产者,而从消息队列里边取数据叫做消费者


举 例:


当你在某团中下单时,正好你又有自己事要去忙,但是你又担心等下小哥突然很快的到来,需要你去接收一下;

正在你忙着忙着的时候,突然接到小哥的电话:

小哥:“你是xx吗?你的快递到了,你可以马上过来拿一下吧!”。

我:“额… 那个我现在还忙,要不你等我一会儿?“。

小哥:“这可不行啊,我还有好多的单子需要去派送呢,要是其他的单子晚送到,肯定要被投诉了”。

于是两个人僵持了很久……

最后小哥说,要不我帮你放到楼下便利店吧,等你忙完了可以过来拿,这回这种局面才解决~

而如果没有便利店或者其他的可以存放的东西的话,则小哥和我情景就应该如下:

def430a296554fa4ae5e30c3c7aa0ee5.png


思考:


1.当小哥打电话来的时候,叫我过去,当时我正在忙的时候,如果这个时候如果过去了,那么可能就耽误到自己的事情,万一很重要呢?
2.但是如果你不过去,而且小哥自己又有苦衷,他也不可能一直的等你。
3.如果没有存放点,那我点的东西不要了?

这个时候就可以看出消息队列的重要性了,就相当于便利店一样,可以作为存放数据,不耽误该服务的工作。

d513ea4bbe3842779261a3d84c2766fc.png


二 、应用场景:


就以上面的例子为说明:

1、 异步

当这位小哥打电话的时候,如果没有存放点,且直到我拿走他上手我的东西之后,他才可能能去送其他人的。当有了存放点的时候,这位小哥就可以将我的东西放在该存放点了,接下来他就可以干其他的活儿去了,不需要等待你到来而一直而处于等待状态,直接大大的提高了工作的效率。


消息发送者 可以发送一个消息而无须等待响应。消息发送者 将消息发送到一条 虚拟的通道(主题 或 队列)上,消息接收者 则 订阅 或是 监听 该通道。一条信息可能最终转发给 一个或多个 消息接收者,这些接收者都无需对 消息发送者 做出 同步回应。整个过程都是 异步的。


2、 解耦

小哥手上有很多快递需要送,而他每次都需要先电话一一确认收货人是否有空、哪个时间段有空,总是要询问一些情况,然后再确定好方案。那么这样的话就完全依赖收货人这边了啊!那么如果快递量大的时候,那这小哥估计的忙疯了……如果有了存放点的话,小哥只需要将同一个小区的快递放在同一个点,然后通知收货人来取货就可以了,这时候小哥和收货人就真正实现了解耦!


系统之间不是 强耦合的,消息接受者 可以随意增加,而不需要修改 消息发送者的代码。消息发送者 的成功不依赖 消息接受者(比如:有些银行接口不稳定,但调用方并不需要依赖这些接口)。

不强依赖 于非本系统的核心流程,对于 非核心流程,可以放到消息队列中让 消息消费者 去按需消费,而 不影响核心主流程。


3、 削峰

假设双十一我买了不同店里的各种商品,而恰巧这些店发货的快递都不一样,有中通、圆通、申通、各种通等……更巧的是他们都同时到货了!这时中通的小哥打来电话叫我去北门取快递、圆通小哥叫我去南门、申通小哥叫我去东门。我一时手忙脚乱……


打平高峰期的流量,消费端可以以自己的速度处理,同时也无需在高峰期增加太多资源,提高资源利用率


三、消息队列通信的模式

1、发布订阅模式

c9a48c2275ec431a976b8457284c8b79.png

发布订阅模型(Pub/Sub) 使用主题(Topic)作为消息通信载体,类似于广播模式。

发布者发布一条消息以后,该消息通过主题传递给所有的订阅者。在一条消息广播之后再订阅的用户则是收不到该条消息的。

如上图所示,发布订阅模式是一个基于消息送的消息传送模型,改模型可以有多种不同的订阅者。生产者将消息放入消息队列后,队列会将消息推送给订阅过该类消息的消费者(类似微信公众号)。由于是消费者被动接收推送,所以无需感知消息队列是否有待消费的消息!但是consumer1、consumer2、consumer3由于机器性能不一样,所以处理消息的能力也会不一样,但消息队列却无法感知消费者消费的速度!所以推送的速度成了发布订阅模模式的一个问题!


假设三个消费者处理速度分别是8M/s、5M/s、2M/s,如果队列推送的速度为5M/s,则consumer3无法承受!如果队列推送的速度为2M/s,则consumer1、consumer2会出现资源的极大浪费!


2、点对点模式


42c799d0e7da4e999a166d78f27180c5.png

使用队列(Queue)作为消息通信载体;满足生产者与消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。


比如:我们生产者发送100条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半。


如上图所示,点对点模式通常是基于拉取或者轮询的消息传送模型,这个模型的特点是发送到队列的消息被一个且只有一个消费者进行处理。生产者将消息放入消息队列后,由消费者主动的去拉取消息进行消费。点对点模型的的优点是消费者拉取消息的频率可以由自己控制。但是消息队列是否有消息需要消费,在消费者端无法感知,所以在消费者端需要额外的线程去监控。


四、消息队列问题


消息队列在实际的应用场景还是很多,但是同时也是有需要去考虑的东西


1 . 数据丢失问题


我们将数据写到消息队列上,系统B和C还没来得及取消息队列的数据,就挂掉了。如果没有做任何的措施,我们的数据就丢了。


学过Redis的都知道,Redis可以将数据持久化磁盘上,万一Redis挂了,还能从磁盘从将数据恢复过来。同样地,消息队列中的数据也需要存在别的地方,这样才尽可能减少数据的丢失。


那存在哪呢?

磁盘?

数据库?

Redis?

分布式文件系统?

同步存储还是异步存储?


2、消费者如何得到数据


消费者怎么从消息队列里边得到数据?有两种办法:
-生产者将数据放到消息队列中,消息队列有数据了,主动叫消费者去拿(俗称push)
-消费者不断去轮询消息队列,看看有没有新的数据,如果有就消费(俗称pull)


3. 高可用


无论是我们使用消息队列来做解耦、异步还是削峰,消息队列肯定不能是单机的。试着想一下,如果是单机的消息队列,万一这台机器挂了,那我们整个系统几乎就是不可用了。


五、 消息队列中间件比较


94cec9822db5489093d77c12f3e4c3c7.png

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
8月前
|
存储 消息中间件 监控
消息队列和应用工具产品体系-ARMS 服务的产品功能
消息队列和应用工具产品体系-ARMS 服务的产品功能
199 0
|
8月前
|
消息中间件 监控 测试技术
消息队列和应用工具产品体系-性能测试场景和工具
消息队列和应用工具产品体系-性能测试场景和工具
88 0
消息队列和应用工具产品体系-性能测试场景和工具
|
3月前
|
消息中间件 NoSQL Java
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
246 1
|
2月前
|
消息中间件 Linux API
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
27 1
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
|
3月前
|
消息中间件 存储 负载均衡
简单入门:消息队列的概念和应用
在复杂的系统架构中,组件间的通信是至关重要的问题。消息队列作为一种解决方案,能够使组件之间的通信更加高效、可靠。本文将从简单到复杂,逐步向您介绍消息队列的概念、使用场景以及如何实现。
100 3
|
4月前
|
消息中间件 监控 负载均衡
Kafka高级应用:如何配置处理MQ百万级消息队列?
在大数据时代,Apache Kafka作为一款高性能的分布式消息队列系统,广泛应用于处理大规模数据流。本文将深入探讨在Kafka环境中处理百万级消息队列的高级应用技巧。
178 0
|
6月前
|
消息中间件 Go 流计算
Golang微服务框架Kratos应用NATS消息队列详解
Golang微服务框架Kratos应用NATS消息队列详解
|
6月前
|
消息中间件 Kafka Go
Golang微服务框架Kratos应用Kafka消息队列
Apache Kafka 是一个分布式数据流处理平台,可以实时发布、订阅、存储和处理数据流。它旨在处理多种来源的数据流,并将它们交付给多个消费者。简而言之,它可以移动大量数据,不仅是从 A 点移到 B 点,而是能从 A 到 Z 的多个点移到任何您想要的位置,并且可以同时进行。
122 0
|
6月前
|
消息中间件 网络协议 物联网
Golang微服务框架Kratos应用MQTT消息队列
MQTT 协议 是由`IBM`的`Andy Stanford-Clark博士`和`Arcom`(已更名为Eurotech)的`Arlen Nipper博士`于 1999 年发明,用于石油和天然气行业。工程师需要一种协议来实现最小带宽和最小电池损耗,以通过卫星监控石油管道。最初,该协议被称为消息队列遥测传输,得名于首先支持其初始阶段的 IBM 产品 MQ 系列。2010 年,IBM 发布了 MQTT 3.1 作为任何人都可以实施的免费开放协议,然后于 2013 年将其提交给结构化信息标准促进组织 (OASIS) 规范机构进行维护。2019 年,OASIS 发布了升级的 MQTT 版本 5。
45 0
|
6月前
|
消息中间件 Go 网络性能优化
Golang微服务框架Kratos应用NATS消息队列
NATS是由CloudFoundry的架构师Derek开发的一个开源的、轻量级、高性能的,支持发布、订阅机制的分布式消息队列系统。它的核心基于EventMachine开发,代码量不多,可以下载下来慢慢研究。其核心原理就是基于消息发布订阅机制。每个台服务 器上的每个模块会根据自己的消息类别,向MessageBus发布多个消息主题;而同时也向自己需要交互的模块,按照需要的信息内容的消息主题订阅消息。 NATS原来是使用Ruby编写,可以实现每秒150k消息,后来使用Go语言重写,能够达到每秒8-11百万个消息,整个程序很小只有3M Docker image
89 0