Redis消息队列

  • KEN
  • 发布于 18小时前
  • 阅读 64

本文旨在记录自己的所学知识,将系统介绍消息队列的基本原理,并通过Redis在实际项目中的应用场景进行说明,所有示例均采用Rust实现。一、什么是消息队列?消息队列(MessageQueue),是分布式系统中重要的组件,它本质上就是一个存放系统行为/消息的一个队列。二、消息队列的作

本文旨在记录自己的所学知识,将系统介绍消息队列的基本原理,并通过 Redis 在实际项目中的应用场景进行说明,所有示例均采用 Rust 实现。

一、什么是消息队列?

<!--StartFragment-->

消息队列(Message Queue),是分布式系统中重要的组件,它本质上就是一个存放系统行为/消息的一个队列。 <!--StartFragment-->

消息队列

<!--EndFragment-->

<!--EndFragment-->

二、消息队列的作用与使用场景

<!--StartFragment--> 在现代云架构中,应用程序被分成了多个独立的更易于开发、部署和维护的模块,而消息队列作为消息传递的中间件,可以为这些模块提供协调和通信,这样做可以显著简化分离应用程序的编码,同时提高性能、可靠性和可扩展性

1. 消息队列系统中的主要角色

一般来说,消息队列系统主要有以下几个角色:

  • 生产者(producer):发送消息到消息队列的角色。生产者主要负责构建消息内容,例如订单请求、更新请求等,以及构造完消息队列之后,将消息投递到消息队列中。

  • 消息队列(message queque/broker):接收、存储、转发消息的中间组件,是消息系统中的神经中枢。主要负责接收生产者消息,对收到的消息进行临时存储以及根据规则将消息投递给消费者。

  • 消费者:接收并处理消息的角色,消费者每次只能消费一个消息。主要负责从队列中拉取或等待消息,对消息执行具体的业务逻辑处理。

一个消息队列系统可以有多个消费者,但是只能有一个生产者。

2.消息队列系统的主要应用场景

消息队列主要解决了应用解耦异步处理以及流量削峰等问题,其通用的使用场景可以简单地描述为:当不需要立即获得结果,但是并发量又需要进行控制的时候,差不多就是需要使用消息队列的时候。

  • 应用解耦 比如说在一些场景中,系统间的多个业务存在关联,例如,在商城中,积分系统需要根据结算系统的结果进行,如果让积分系统直接依赖结算系统的结果,可能会出现积分系统失败导致结算系统失败的请请款,这就是因为业务间的耦合度太高,如果使用消息队列,可以解耦业务耦合度。结算系统完成之后,将数据扔到消息队列中,积分系统从消息队列中拿数据。

  • 异步处理 将一些非核心的业务流程以异步并行的方式执行,从而减少系统请求响应时间,提高系统吞吐量。

  • 流量削峰 流量削峰一般存在于比如说秒杀活动中,在此情况下,系统收到的请求数量大量增加,此时为了保证系统的稳定性,可以采用消息队列,让请求一个一个的被处理。

<!--EndFragment-->

三、redis用作消息队列

redis提供了三种消息队列的使用方法,分别是List模式,pub/sub订阅模式以及stream模式。

1.List模式

<!--StartFragment-->

List本身就是按照先进先出的顺序对数据进行存取的,所以,如果使用List作为消息队列保存消息的话,就已经能够满足消息报序的需求了。

对于高吞吐/主动轮询的系统,List模式提供了LPUSH + RPOP(左进右出)这样的指令;对于低功耗/实时响应类消费场景,List模式提供了LPUSH + BRPOP的模式,在队列中没有消息时,会进行阻塞,阻止cpu资源消耗。

同时List模式提供了ACK机制,ACK即处理这样一种场景,因为消息队列中的消息被消费者取出之后,消息便会消失,所以如果消费者取出消息之后,没有成功的处理消息对应的动作,这个动作便无法完成了。List模式提供的ACK模式的具体解决方式是,提供一个新的队列,来保存消费者处理的消息,直到改消息被成功处理才会从ACK队列中移除该消息。 <!--EndFragment-->

2.pub/sub模式

<!--StartFragment-->

"发布/订阅"模式包含两种角色,分别是发布者和订阅者。订阅者可以订阅一个或者多个频道(channel),而发布者可以向指定的频道(channel)发送消息,所有订阅此频道的订阅者都会收到此消息。

Redis 通过 PUBLISH 、 SUBSCRIBE 等命令实现了订阅与发布模式, 这个功能提供两种信息机制, 分别是订阅/发布到频道和订阅/发布到模式。

这个 频道 和 模式 有什么区别呢?

频道我们可以先理解为是个 Redis 的 key 值,而模式,可以理解为是一个类似正则匹配的 Key,只是个可以匹配给定模式的频道。这样就不需要显式的去订阅多个名称了,可以通过模式订阅这种方式,一次性关注多个频道。 <!--EndFragment-->

3.stream模式

<!--StartFragment-->

到目前为止,list 实现的队列都没能很好的支持多消费组的场景;当然,你可能会想,按照多消费者组的场景,也可以接着写下去;但是,复杂就飙升了,还容易出错。

同时订阅 (pub/sub) 也有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。而且也没有 Ack 机制来保证数据的可靠性,假设一个消费者都没有,那消息就直接被丢弃了。

Redis 从 5.0 版本开始提供的 Streams 数据类型,是为 redis 设计的消息队列,能支持多消费组的场景。

<!--EndFragment-->

四、redis做消息队列的案例

五、其他补充

死信队列

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
KEN
KEN
0x4e16...2573
江湖只有他的大名,没有他的介绍。