消息队列面试题

1.  消息队列的作用
  • 应用解耦
    如果有订单系统,下单成功后,需要调用库存系统扣减库存;随着公司业务的发展又需要增加物流系统接收下单信息;此时又需要订单系统增加调用物流系统的代码;但是增加队列后,订单系统只需要将下单信息发送到队列,其他系统需要这个消息来订阅就可以;并且也不会因为库存系统异常导致下单失败。
  • 异步提速
    用户注册陈功后,需要先将数据保存,并且发送邮件通知,邮件通知成功后再发送短信通知,短信通知成功后才响应客户成功消息。用户体验感很差。增加消息队列后,只需要保存数据,将发送邮件通知和短信通知消息发送到消息队列,可以很大程度提升响应速度。
  • 流量削峰
    如果订单系统每秒只能处理1K的请求量,但是在某一瞬间,比如秒杀,每秒可以达到1W甚至更多的请求,这种情况下可能会直接导致订单系统崩溃;增加消息队列后,订单系统每拉取1K请求,可以很平稳的去消费消息。
2. 消息队列有什么缺点
  • 降低系统的可用性:系统引入的外部依赖越多,越容易挂掉;
  • 系统复杂度提高: 使用MQ后可能需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题;
  • 一致性问题: A系统处理完了直接返回成功了,但问题是: 要是 B、C、D三个系统里,B和D两个系统写库成功了,结果C系统写库失败了,就造成数据不一致了。
3. 如何保证消息队列的顺序性
  • 生产者有序的情况下,单线程消费来保证消息的顺序性
  • 生产者无序的情况下,对消息进行编号,消费者处理时根据编号判断顺序。多个消费者,可以考虑增加分布式锁
4. 如何保证消息不被重复消费/如何保证消息的幂等性
  • 生产者发送的每条数据的时候,里面添加一个全局唯一的ID,消费者消费到消息后,肖根据消息id去redis查询一次,如果redis不存在,就处理消息、然后再将消息id写入redis。如果reids中存在,说明消息已经消费国了,就不用处理了。
  • 基于数据库的唯一键,保证重复数据不会重复插入。因为有唯一键的约束,所以重复数据只会插入报错,不会导致数据库中出现脏数据。 
5. 如何保证消息不丢失

保证消息不丢失我们可以从一下介个方面来分析,以RabbitMQ为例:

  • 生产者丢失消息
    丢失原因: 发送消息过程中出现网络问题:producer以为发送成功,但是RabbitMQ server 没有收到。
    解决方案: 发送发确认机制,在生产者端开启comfirm确认模式,每次写入的消息都会分配一个唯一的ID,然后写入RabbitMQ中,RabiitMQ会给你回传一个ack消息,告诉你说这个消息OK了
  • 队列丢失消息
    丢失原因:暂存内存中,还没消费,队列自己挂掉了,数据都会丢失
    解决方案:
    • MQ设置为持久化。将内存数据持久化到磁盘中;
    • 开启镜像队列
    • 持久化到磁盘中也并不能保证100%不丢失数据,可能在写入磁盘过程中宕机;这事可以开启生产者comfirm确认模式
  • 消费者丢失消

        丢失原因:消费者丢失数据一般是因为采用了消息自动确认模式。这种模式下,消费者会自动确认收到的消息。这时RabbitMQ会立即将消息删除,这种情况下,如果消费者出现异常而未能处理消息,就会丢失该消息。
        解决方案:
       
采用手动确认消息即可,RabbitMQ提供的ack机制,就是你必须关闭RabbitMQ的自动ack,可以通过一个api来调用就行,然后每次你自己代码里确保处理完的时候,再在程序里ack一下。这样的话,如果你还没处理完,不久没有ack了;那RabbitMQ就认为你还没处理完,这个时候RabbtiMQ会把这个消息分配给别的consummer去处理,消息是不会丢失的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值