一、简介
MQ 代表消息队列,一端仅不断向队列发布信息,另一端仅从队列中读取消息。阅读消息的人不必担心消息是谁发布的,每个人都可以做自己的事情,互不干扰。
市场上常用的消息队列有:RabbitMQ、RocketMQ、Kafka、ActiveMQ。
二、MQ的优势
(1) 解耦
使用Message MQ后,只需保证消息格式没有改变,无需担心发布者和消费者之间的关系。以便互相沟通。
(2) 异步
某些不需要立即返回(同步)结果的操作通过消息队列进行异步实现。
(3) 削峰
如果请求量较大(秒杀场景),可以使用消息队列进行缓冲,抑制高峰流量,避免系统短时间内被高峰流量淹没。
场景:在流量高峰期,如果您的数据库只能承受2000个并发流量,您可以使用MQ来控制您的数据库的2000个并发流量。
(4) 日志处理
日志存储在消息队列中,用于kafka等处理日志。
三、MQ的劣势
系统可用性将会降低。在MQ之前,系统只需要考虑生产端和消费者端接口的一致性。实施后,应注意系统的稳定性。这增加了生产、MQ、消费端的负载,增加了系统运维成本。
随着系统复杂度的增加以及MQ的引入,需要考虑更多的问题,比如如何保证消息一致性,防止重复消费。
一致性问题:系统A发送消息后直接返回成功,但BCD系统中任何一个系统写入数据库失败,就会出现数据不一致的情况。
四、常见问题
(1) 怎么保证消息没有重复消费?使用消息队列如何保证幂等性
幂等性:同一操作的一次或多次用户发起请求的结果是一致的,并且不存在多次点击带来的副作用。
问题的原因
首先我们先了解一下为什么消息会被重复消费。使用MQ的过程中存在三种角色:生产者、MQ、消费者。然后您将看到该消息的重复。
生产者:生产者可以将重复的数据推送到MQ。这可能是由于控制器接口被发送两次或重试机制造成的。 MQ:假设网络波动,消费者消费完消息后发送ACK和MQ。由于在接受消息之前调用突然挂断,MQ判定消费者没有消费该消息,在MQ响应后,再次推送该消息,导致重复消费。 Consumer:消费者收到消息后,尝试向MQ发送ack,但它认为此时消费者还没有消费该消息,所以MQ推送它。又是这个消息。解决方案
一般情况下,生产者就是客户,很难避免用户的重复点击,但MQ不允许多条相同的消息。因此,MQ 被实现为幂等的。消费端:
状态判断:当消费者想要重新消费时,首先访问redis判断数据是否存在,则表示已被消费,消费完后直接丢弃。如果需要将数据插入数据库,请使用数据库唯一约束来防止重复使用。在将数据插入数据库之前检查数据是否存在。如果数据存在的话,这个方法是解决问题的一个比较简单粗暴的方法。
在生产端发布消息时,方法每发布一条消息,都会在消息体中记录上一条消息的ID。当消费者收到消息时,它会执行以下操作:
首先根据之前的ID检查是否还有之前未消费的消息。如果不存在(消费后删除ID),正常操作会访问数据库,检查是否存在。如果是基于ID进行消费,如果正常操作中没有被消费,则会休眠一定时间(例如30ms),并重新检查是否正在被消费。如果不进行正常操作,会抛出异常
(2) 消息丢失的情况
。根据消息的严重性,分两种情况进行处理。
如果可以的话,直接丢弃该消息。由于一般情况下消息是无法丢弃的,所以应该考虑一种策略,将原来的消费端复用为生产端,有一天重新部署MQ。则显示消费者端,形成另一条生产-消息-消费者线。
版权声明:本文转载于今日头条,版权归作者所有。如有侵权,请联系本站编辑删除。