消息队列复习-基础知识

66 阅读2分钟

消息队列的作用

异步、削峰、解耦

异步:

防止多个任务在同一个程序中执行,比如A、B、C三个功能,如果每次程序执行都需要顺序执行ABC三个模块,那么程序会越来越慢, 如果ABC三个功能没有顺序性要求可以通过消息队列进行异步处理,

解耦:

就向如上所说,三个功能不同的代码块,放在一起,每次添加新功能都要重新部署整个程序,并且代码越来越臃肿,更难以维护。

削峰:

在高并发的场景下,如果流量全部打进来,那么redis、mysql可能无法承受能力,使用消息队列,实现了系统自己调节压力,最大的问题顶多会慢一些,不至于服务异常。

问题:

1、提升了系统的复杂性

2、数据一致性:不能通过简单的事务操作,需要分布式事务。

3、可用性降低:需要额外维护消息队列的可用性

引发的问题:

重复消费:

如果消费某个消息队列的下游中的某一个服务出现问题,那么需要消息队列进行数据的重传,由于多个服务同时订阅了这个消息,那么其他正常的服务可能出现重复消费的问题。

解决方案:

保证幂等性,可以通过任务标识来进行判断,比如操作时将唯一性id写入redis,每次判断这个id是否被记录过,也可以其他方式记录

顺序消费:

如果服务对任务数据的顺序性有要求,如增删改查操作,结果消费顺序变为了删改增查,那么系统就是不可靠的,因此需要保证消息的顺序性。

解决方案:

如果一个topic有多个队列同时进行消费,RocketMq解决方案是根据某个key值得hash来选择不同的队列,因此同一个订单号会走同一个队列,发送的顺序必然是顺序的,但是接受的顺序需要在接受端进行校验。

分布式事务:

两个系统内的事务操作无法通过普通的事务操作实现。

解决方案:

这里介绍两种2pc提交和最终一致性提交

2pc提交

A和B都按顺序进行事务操作,但是操作结束后并不提交,等待两者都告知了协调者中间件,那么此时中间件会通知两者进行提交。

最终一致性:

A系统先和消息中间件进行沟通,当A系统告诉了中间件成功,此是中间件再向B系统发送信息,保证了A如果不成功,B一定不会受到消息。