这是我参与「第五届青训营 」伴学笔记创作活动的第14 天
今天学习了消息队列的相关内容。
MQ概念
1、什么是MQ
MQ(Message Queue)消息队列,字面来看就是存放消息的队列。它是一种跨进程的通信机制,主要用于上下游传递消息。生产者产生消息并把消息放入队列,然后由消费者去处理。在互联网架构中,MQ 是一种非常常见的上下游解耦的消息通信服务。
2、为什么使用MQ?(MQ的优点)
异步处理 - 相比于传统的串行、并行方式,提高了系统吞吐量。 应用解耦 - 系统间通过消息通信,不用关心其他系统的处理。 流量削峰 - 可以通过消息队列长度控制请求量,缓解短时间内的高并发请求。 日志处理 - 解决大量日志传输。 消息通讯 - 消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。
3、什么是解耦、异步、流量削峰
异步: 主要是为了提升响应速度。我们经常会遇到这样的业务场景:用户注册成功后,给它发个短信和发个邮件。如果注册信息入库是 30ms,发短信、邮件也是 30ms,三个动作串行执行的话,会比较耗时,响应 90ms:
如果用消息队列实现异步,注册信息入库成功后,写入到消息队列(这个一般比较快,如只需要 3ms)立即返回,随后异步读取发邮件和短信,总共的响应就只需要33s。
流量削峰:减少流量高峰时期对服务器压力。一些秒杀服务中,需要避免流量暴涨,击垮应用系统的风险。可以在应用前面加入消息队列。假设秒杀系统每秒最多可以处理 2k 个请求,每秒却有 5k 的请求过来,可以引入消息队列,把请求先缓存到消息队列中,然后秒杀系统每秒从消息队列拉 2k 请求处理,把这5k个请求分散成一段时间来处理。
这样会出现消息积压的问题吗?不会!
- 首先秒杀活动不会每时每刻都那么多请求过来,高峰期过去后,积压的请求可以慢慢处理;
- 其次,如果消息队列长度超过最大数量,可以直接抛弃用户请求或跳转到错误页面;
解耦: 以电商应用为例,应用中有订单系统、库存系统、物流系统、支付系统。用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障,都会造成下单操作异常。而且我们必须要等所以系统都执行成功后,才可以响应给用户,造成用户等待时间过长。当转变成基于消息队列的方式后,系统间调用的问题会减少很多,比如物流系统因为发生故障,需要几分钟来修复。在这几分钟的时间里,物流系统要处理的消息被缓存在消息队列中,用户的下单操作可以正常完成。当物流系统恢复后,继续处理订单信息即可,下单用户感受不到物流系统的故障,提升系统的可用性。
4、MQ的缺点
系统可用性降低: 本来系统运行好好的,加入个消息队列进去,如果消息队列出现故障,整个系统也会出现故障。因此,系统可用性会降低;
系统复杂度提高: 加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。因此,需要考虑的东西更多,复杂性增大。
一致性问题: A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库。加入mq后,当 A 系统处理完直接返回成功,但是问题是, 如果 BCD 三个系统中任意一个系统写库失败了,数据就出现不一致问题了。 至于如何解决这个问题,可以采用事务消息。
总结:消息队列实际是一种非常复杂的架构,引入它有很多好处,但是针对它带来的坏处需要做各种额外的技术方案和架构来规避掉,这也会提升系统复杂度。