您当前的位置: 首页 >  华为

阿里百度华为消息队列MQ异步场景面试题

发布时间:2020-11-28 23:04:48 ,浏览量:0

1 案例一

用户注册后,发消息到MQ,然后会员服务监听消息异步处理。有时发现,虽然用户服务先落库再发MQ,但会员服务收到消息后去查询DB,却发现DB还没有新用户信息。why?

1.1 可能原因

用户注册的代码端把异常都吞了,没抛出来,而用户注册又报错了,但还是继续执行并发了MQ消息。

可能数据写到了主库,然后查询的从库。但因主从延迟,导致没查询到。

有时因为业务代码 数据落库 和 发MQ消息 放在一个事务,有一定概率收到消息时,事务还没提交完成。当时处理方式是收到MQ消息时sleep 1s,或许应先提交事务,完成后再发MQ消息。

但这又出来一个问题:发消息失败怎么办?后来建立本地消息表,确保MQ消息可补偿,把业务处理和保存MQ消息到本地消息表操作放在同一事务内处理,然后异步发送和补偿发送消息表中的消息到MQ。

  1. 先保存用户注册的数据,同时记录下要发送MQ的消息,这两个入库在一个事务

  2. 异步任务,定时拉取MQ的消息表,发送到MQ进行处理

这就是本地事务消息的实现,第2步不一定非得定时任务拉取到。第1步完成后直接发MQ即可, 定时任务拉取只是用来做补偿。

  • 若有多个补偿实例,会不会造成消息重复? 补偿需要配合幂等,生产应用肯定用DB做幂等(如消息id)。

  • Pro发消息给MQ,即使异步发送,也会有listener来监听投递消息是否成功。若失败,也可重试。

2 案例二

除了使用Spring AMQP实现死信消息的重投递外,RabbitMQ 2.8.0后支持的死信交换器DLX也可以实现类似功能。

自定义的死信队列,其实是发送失败,主要是生产者发送到MQ时,发送失败,进入自定义的死信队列。 DLX是因为如下导致消息无法到达正常队列:

  • 消息消费时被拒绝(basic.reject / basic.nack),且requeue = false

  • 消息TTL过期

  • 队列达到最大长度

  • 技术分享RabbitMQ的资料 http://note.youdao.com/noteshare?id=e9f2f88c6c7fcb7ac690463eb230650a

关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    115984博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.1025s