消息队列MQ使用详解
作者:Lvan的前端笔记
什么是消息队列MQ
MQ(Message Queue)消息队列,是基础数据结构中“先进先出”的一种数据结构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。
消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。
作用
消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。
- 解耦:一个业务需要多个模块共同实现,或者一条消息有多个系统需要对应处理,只需要主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合。
- 异步:主业务执行结束后从属业务通过MQ,异步执行,减低业务的响应时间,提高用户体验。
- 削峰:高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪。
缺点
1、系统可用性降低。依赖服务也多,服务越容易挂掉。需要考虑MQ瘫痪的情况
2、系统复杂性提高。需要考虑消息丢失、消息重复消费、消息传递的顺序性
3、业务一致性。主业务和从属业务一致性的处理
主要产品
主要的 MQ 产品包括:RabbitMQ、ActiveMQ、RocketMQ、ZeroMQ、Kafka、IBM WebSphere 等。
比较火的是 RocketMQ 和 Kafka。
分别应用在 web 和大数据
举例
1、例一
一个实际的使用消息队列(MQ)的例子是电商网站的订单处理系统。在电商网站中,用户下单后需要经过一系列的处理流程,包括订单验证、库存检查、支付处理、物流跟踪等。这些处理流程需要多个模块之间进行协作,而且每个模块都需要处理大量的订单数据。
为了解决这些问题,可以使用消息队列系统来实现订单处理流程的异步处理。具体来说,可以将订单数据发送到一个订单处理队列中,然后由不同的模块从队列中获取订单数据进行处理。这样就可以将订单数据的发送和接收者进行解耦,实现了系统的高可靠性、可伸缩性和可维护性。
举个例子,当用户下单后,订单系统会将订单数据发送到订单处理队列中,然后库存系统会从队列中获取订单数据进行库存检查,支付系统会从队列中获取订单数据进行支付处理,物流系统会从队列中获取订单数据进行物流跟踪等。这些模块之间可以并行处理订单数据,而且每个模块都可以独立地进行扩展和升级,从而实现了系统的高可用性和可伸缩性。
另外,由于电商网站的订单数据量可能非常大,使用消息队列可以实现削峰填谷,平滑处理订单请求,从而保证系统的可用性和稳定性。此外,使用消息队列还可以实现订单数据的缓存和延迟处理,以提高系统的性能和吞吐量。
总之,使用消息队列可以使得电商网站的订单处理系统更加高效、可靠和可维护,是现代电商系统中必不可少的技术。
例二
在线游戏中的多人游戏场景同步。在多人游戏中,多个玩家之间需要实时同步游戏场景的状态,包括角色位置、状态、动作等,同时还需要处理玩家之间的交互、碰撞等复杂场景逻辑。
为了实现这样的实时场景同步,可以使用消息队列来处理游戏场景事件的分发和处理。具体来说,可以将游戏场景中的事件(如玩家移动、攻击、技能释放等)封装成消息,然后通过消息队列进行广播,让所有参与游戏的客户端都能够接收到相应的消息,并根据消息内容来更新本地的游戏状态。
使用消息队列的好处在于,它可以将游戏场景事件的发送和接收者进行解耦,从而提高系统的可扩展性和可维护性。同时,由于消息队列可以处理大量的消息,还可以应对高并发的场景,并且能够削峰填谷,提高系统的稳定性和可用性。
在多人游戏中,使用消息队列还可以实现一些高级功能,比如实现延迟同步、反作 弊等。比如,可以将游戏场景中的事件缓存到消息队列中,并设置一定的延迟时间后再进行处理,以确保所有玩家都能够接收到相同的游戏状态。此外,还可以使用消息队列来监控和过滤玩家的行为,以检测和防范作弊行为。
综上所述,使用消息队列可以实现多人游戏场景的实时同步,并提高系统的可扩展性、可维护性和稳定性,是现代游戏开发中的重要技术。
例三
用户注册后,需要发注册邮件和注册短信,传统的做法有两种
- 1.串行的方式;
- 2.并行的方式 ;
- 3.消息队列
(1)串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才返回给客户端。这有一个问题是,邮件,短信并不是必须的,它只是一个通知,而这种做法让客户端等待没有必要等待的东西。
(2)并行方式:将注册信息写入数据库后,发送邮件的同时,发送短信,以上三个任务完成后,返回给客户端,并行的方式能提高处理的时间。
(3)消息队列
引入消息队列后,把发送邮件,短信不是必须的业务逻辑异步处理。
例四:流量削峰
秒杀活动,一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。
用户的请求,服务器收到之后,首先写入消息队列,加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面。秒杀业务根据消息队列中的请求信息,再做后续处理。
发布订阅 vs MQ
发布订阅模式和消息队列(MQ)都是在分布式系统中广泛使用的消息传递机制,它们都具有将发送者和接收者解耦的优点。
虽然这两种模式在某些方面相似,但它们也有一些重要的区别。
谁负责管理消息?
- 在发布订阅模式中,消息的发送者不需要知道消息的接收者,而是将消息发送到一个主题(Topic),然后所有订阅该主题的订阅者都会接收到该消息。主题的管理通常由发布者负责。
- 在消息队列中,消息的发送者将消息发送到队列中,然后订阅该队列的订阅者会按照队列中的消息顺序进行消费。队列的管理通常由消息队列系统负责。
消息如何分发?
- 在发布订阅模式中,消息是通过主题进行分发的,所有订阅该主题的订阅者都会接收到相同的消息。这种方式可以使得多个订阅者同时接收到同一份消息。
- 在消息队列中,消息是通过队列进行分发的,每个消息只会被一个订阅者接收。这种方式可以确保每个订阅者都能够接收到所有消息,但是无法让多个订阅者同时接收到同一份消息。
如何处理消息丢失?
- 在发布订阅模式中,如果某个订阅者没有及时接收到消息,它将无法再次获取到该消息。这可能会导致消息丢失。
- 在消息队列中,消息通常会被持久化到磁盘上,以确保即使在消息消费者宕机的情况下,消息也不会丢失。如果某个消费者无法消费某个消息,该消息将被保留在队列中,直到可以被正确地处理为止。
用例场景
- 发布订阅模式通常适用于一些事件驱动的应用场景,例如消息推送、实时数据处理等。
- 消息队列则适用于一些流量高、性能稳定的场景,例如电商交易、订单处理、日志处理等。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。