共计 1842 个字符,预计需要花费 5 分钟才能阅读完成。
作者:Ccww
链接:https://juejin.im/post/5dd3b5…
场景一:系统解耦
假设你有个系统 A,这个系统 A 会产出一个核心数据,现在下游有系统 B 和系统 C 需要使用这个数据。
首先想到最简单,系统 A 就是直接调用系统 B 和系统 C 的接口发送数据给他们就好了
但是现在要是来了系统 D、系统 E、系统 F、系统 G,等等,十来个其他系统都需要这份核心数据呢?
这是可能会出现开发人员最头疼的、尴尬的问题?
先是来一个人找他要求发送数据给一个新的系统 H,系统 A 的同学要修改代码然后在那个代码里加入调用新系统 H 的流程。
一会那个系统 B 是个陈旧老系统要下线了,告诉系统 A 的同学:别给我发送数据了,接着系统 A 再次修改代码不再给这个系统 B。
那我们现在该怎么做呢?系统的耦合性那么高,这真是牵一发而动全身,小需求需要大改动,何必呢?
现在我们主角要来了,可以使用 MQ 消息中间件,让我们系统之间耦合度降低。
现在我们只需要将系统 A 自己的一份核心数据发送到 MQ 中间件中,下游哪个系统感兴趣自己去消费即可。
这样能达到一次编译不必改,谁爱谁去改,反正我不改。
总结:通过 MQ 消息中间件的使用,重构系统之间的耦合,让系统具备高度的可扩展性。
场景二:异步调用
假设你有一个系统调用链路,是系统 A 调用系统 B,一般耗时 20ms;系统 B 调用系统 C,一般耗时 200ms;系统 C 调用系统 D,一般耗时 2s
用户一个请求过来巨慢无比,就像走过长长的套路一样
因为走完一个链路,需要耗费:
20ms + 200ms + 2000ms(2s)= 2220ms,
也就是 2 秒多的时间。但是实际上,链路中的系统 A 调用系统 B,系统 B 调用系统 C,这两个步骤起来也就 220ms。
这时候主角大佬又慢慢的过来了,这都搞不定,不是很简单吗?
实现思路就是系统 A -> 系统 B -> 系统 C,直接就耗费 220ms 后直接成功了。
然后系统 C 就是发送个消息到 MQ 中间件里,由系统 D 消费到消息之后慢慢的异步来执行这个耗时 2s 的业务处理。通过这种方式直接将核心链路的执行性能提升了 10 倍。
总结:
- 1)对用户来说,比同步时更加快捷,用户体验非常好。(让用户以为自己抢到了,欺骗 ing)
- 2)对系统访问压力来说,异步因为没有真正执行,不会造成某时刻对系统的访问压力剧增,而是放入队列,慢慢去消费!
场景三:流量削峰
假设你有一个系统,平时正常的时候每秒可能就几百个请求,系统部署在 8 核 16G 的机器的上,正常处理都是 OK 的,每秒几百请求是可以轻松抗住的。比如秒杀活动
在秒杀活动在高峰期一下子来了每秒钟几千、万请求,弹指一挥间出现了流量高峰。
如果时候出现机器宕机,公司损失可是大大的,这是你是不是该准备好被老板痛骂,甚至可能要 say goodbye
可能想到的解决的方式,线上部署了很多台机器,一多制胜的方法:
但是,假设除了秒杀活动达到瞬时高峰,其它时间基本为每秒就几百请求,如果你线上部署了很多台机器,就是为了这次秒杀活动,这有点浪费机器资源。
所以这时,MQ 大哥又出现了,不怕,这不是还有我吗?
在所有机器前面部署一层 MQ,平时每秒几百请求大家都可以轻松接收消息。一旦到了瞬时高峰期,一下涌入每秒几千的请求,就可以积压在 MQ 里面,然后那一台机器慢慢的处理和消费。
总结:削峰从本质上来说就是更多地延缓用户请求,以及层层过滤用户的访问需求,遵从“最后落地到数据库的请求数要尽量少”的原则。
总结
解耦与复用
系统 A 要发送一个消息到多个系统,如果此时每增加一个系统,系统 A 都需要通过修改源码来增加接口,此时耦合非常高,但是如果中间使用消息队列的话,系统只需要发送一次到消息队列,别的系统就能复用该信息,当增加或删除系统调用接口的时候,不需要额外的更新代码。
异步
用户调用一个接口的时候,可能该接口调用了别的方法。例如:用户注册的时候,后台可能需要调用:查询数据库,插入数据库,发送邮件,发送用户指南等等 …
但是用户可能并不需要后台将所有的任务执行完毕,那么此时在初入数据口后面加入 mq 队列,用户就能很快得到注册成功的响应而去做一些别的事情。mq 的机制又能保证最终的一致性,所以使用起来很安全很稳定。
削峰
何为削峰,就是当系统压力过大的时候,让系统压力减小。如何做?
比如,平时可能数据库的读写每秒几百,在流量高峰期,系统的访问达到了每秒 10000。此时由于加入了消息队列,所以不会出现激增的访问导致系统奔溃。
削峰并不会让用户的等待时间减少,所以一般会跟异步搭配来使用
最后 MQ 还有其他场景,通知、数据分发等等,能体现使用 MQ 中间件的好处。