现在的互联网应用,分布式系统中都避不开两个要素,一个是高速的存储比如redis,memecache,另一个是消息队列,刚开始接触MQ是在刚毕业不到一年的时候,做一个政务系统,里面设计到了户籍验证,婚姻验证两个独立的工程,我在代码里找了半天找不到两个系统之间接收消息调用的接口,问老大,他说是靠订阅MQ来接收的,当时我一脸懵逼,,还有这种操作,,哈哈哈,现在想起来觉得好逗。
动机
按现在的行情,微服务化已经是个普遍趋势(可能过不了几年微服务都过时了,开始普遍ServiceMesh了)。每一个工程之间的功能都是尽可能独立的,系统和系统之间的调用按照传统做法最多的是使用httpclient,去直接远程调接口,但是这样做会产生一些问题:
- 系统和系统之间的代码存在耦合,为了跟这个系统对接选择的参数都是指定的,如果将来又要对接另一个系统将数据发送过去,岂不是又要去更改代码。那么代码就要处于不停的变动当中(现在搞的CRM系统也是这样,,来一个用户一个特别的需求,,就要忙活半天,,,,烦躁。想想怎么优化吧。。)
- 高并发场景下,直接使用http请求调用如果服务端的处理能力跟不上,那么会造成拥堵阻塞,吞吐量很快达到瓶颈
所以这种场景下,MQ闪亮登场!
作用
MQ的作用嘛,按照面试题的套路,无非是:解耦,异步,削峰。
- 解耦
关于解耦的这个作用其实就是我上面说到的第一个问题,频繁的改动,不如把我要给的消息扔到一个地方,谁想拿谁拿去。这样就完美的将系统和系统之间通过第三方隔离开。跟别的公司的人对接的时候,把MQ地址一扔就雨我无瓜了~ - 异步
按照官方点的解释,这是为了让提高响应速度。收到请求后,将消息扔到MQ上,而不需要等待系统写库成功后才返回。但其实这一点上我觉得现在有很多框架都已经实现了异步Future的操作,这一点不是只有MQ才可以做到的,比如我现在常用的Play框架,异步非阻塞,底层使用netty,和现在的WebFlux一个性质。在用户体验上都可以实现很好的提升。 - 削峰
这一点确实我觉得确实是中间件存在的重要意义。先说下我的场景,当时是做的医保卡刷卡消费系统,刷了医保卡后会发短信你那种,用户量高峰集中在早上9点到11点,下午1点到4点,看病取号大多都在这些时间段里。如果我使用直接从接口接收数据存入MYSQL的方式,在高峰阶段是处理不过来的(记得当时每分钟会产生四千多条数据),这种时候数据库就成了性能瓶颈。所以在中间搭了MQ,高峰时期的数据来了就堆积在MQ上,消费端依旧是按自己可接受的吞吐量来处理请求。这里我们是在写MQ成功的时候就直接发送通知给用户,然后后端从MQ接收用户数据落地到MYSQL中。
优缺点
MQ是个神器,优点在上面已经说了,还是挺刚需的,要说缺点的话就是提高了系统的复杂度,因为在系统中添加进一个中间件,不可避免的就要开始考虑高可用,可靠性等问题。比如MQ本身的高可用,如何保证数据在链路中的一致性,如果保证数据不丢失。要因此写的处理逻辑会很多。