MQ常见问题

  1. 为什么要选择使用MQ?
    通过MQ可将系统解耦,实现不同的系统之间通信;
    异步处理;
    流量削峰。

    解耦:
    场景:系统A生产完数据后需要调用系统B,系统C以及系统E的接口。当新增一个系统D时,需要在系统A中新增调用代码,系统E去除时,也要在系统A中删除调用接口代码。系统严重耦合。
    系统A还需要考虑其他系统是否挂掉,重发消息等问题。
    解耦场景
    使用MQ的场景如下图:
    在这里插入图片描述
    系统A不需要考虑谁需要这条消息,系统解耦。

    异步处理:
    场景: 当用户注册成功后,邮箱、手机等需要收到注册成功的消息。可能短信调用接口需要200ms,邮箱接口需要200ms,其他系统接口需要500ms,总时间累加后,系统变慢,用户体验较差。
    在这里插入图片描述
    使用MQ:通过MQ异步发送短信邮件。系统响应速度变快。
    在这里插入图片描述
    流量削峰
    场景:秒杀系统,并发请求量过大,假设每秒5000个请求,系统可能问题不大,mysql却抗不住,可能直接导致mysql死机,系统崩溃。
    在这里插入图片描述
    加入MQ后,系统将用户请求进入MQ,然后每秒取出2000个,系统不会崩溃。不过可能会导致消息积压。
    在这里插入图片描述

  2. 使用MQ会出现的问题。
    1). 可能会出现数据丢失。
    生产者丢失数据,通过MQ提供的事务,或者在生产者开启confirm 模式,每次推送数据时,MQ会回传ack消息,则数据推送成功。
    MQ宕机发生数据丢失,开启数据持久化来解决,有可能数据还未持久化,MQ宕掉后,则会发生这一小部分数据丢失。
    消费端丢失数据,消费的时候,刚消费到,还没处理,结果进程挂了,比如重启了,使用ack机制解决。

    2). 可能会出现重复消费。
    重复消费有不同的层次,当update/delete/select 操作,应该都是幂等操作,可以允许重复消费。
    但是insert不是幂等操作,重复消费则会insert多次数据,导致数据重复。
    但也必须要分场景,例如 转账的场景中,update不是幂等的操作。

    重复消费场景:
    系统A -> MQ -> 系统B
    加入提交数据至MQ没有异常,系统B能够拉取到数据,当系统B拉取消息成功后,并且将数据落地成功,消费成功,此时的系统B刚好down掉,则没有返回ack给MQ,MQ不知道该消息被正确的消费了。系统B恢复正常后,重新拉取数据,则发生重复消费。
    在这里插入图片描述
    3). 如何避免重复消费 实现exactly once 需要根据业务来决定。
    方案一:
    Kafka中,每个partition里每个group都维护了一个offset 将 group信息 和 offset 信息 与数据同时落地到数据库当中,
    当consumer down掉后,不从Kafka中获取offset,而是从数据库当中获取最后一条offset+1进行消费。
    也就是将offset从Kafka维护变成了本地维护,实现exactly once。
    方案二:
    MQ中存储全局唯一ID,生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。

    根据业务场景分析,如果重复消费是幂等的,则可以恰好不解决。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值