消息队列MQ详解

为何选择使用消息队列

  咱们不会无缘无故引入一个技术栈,必定是看重它的某些特性,毕竟引入一个技术可能存在弊端和风险。咱们在谈论为何使用消息队列的时候必定要根据具体业务来,好比在实际业务中遇到了什么困难,若是不使用消息队列就很棘手,经过使用消息后解决了哪些问题。这里总结了三点比较核心缘由:解耦、异步、削峰。git

解耦

  在某个场景下,A系统须要向BCD系统经过接口调用发送一条数据过去,这个时候E系统也要数据,D系统也要数据,此时A系统心里确定是崩溃的。github

  上诉场景中A系统和其余系统耦合性很高,每当产生一条数据的时候A系统都要考虑到其余系统是否在线?是否挂掉?是否接收正常?因此A系统真的是太难了!apache

  若是使用MQ,A系统产生一条数据后就放进MQ,其余系统须要就本身到MQ系统中去消费,不须要就能够取消对该消息的订阅,A系统压根不须要再考虑给其余系统发送数据的各类乱七八糟问题。架构

  总结:经过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统完全解耦了。并发

异步

  在某场景下,A系统收到一条数据后须要在本身本地写库,同时还要在BCD三个系统写库,本身本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。总共要延时3 + 300 + 450 + 200 = 953ms,接近 1s啊,对强迫症的人来讲简直要爆炸!异步

  正常一个请求控制在200ms左右,客户是没有感知的。大数据

  若是使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms,对于用户而言,其实感受上就是点个按钮,8ms 之后就直接返回了,爽!网站作得真好,真快!美滋滋!网站

削峰

天天 0:00 到 12:00,A 系统风平浪静,每秒并发请求数量就 50 个。结果每次一到 12:00 ~ 13:00 ,每秒并发请求数量忽然会暴增到 5k+ 条。可是系统是直接基于 MySQL 的,大量的请求涌入 MySQL,每秒钟对 MySQL 执行约 5k 条 SQL。日志

  通常的 MySQL,扛到每秒 2k 个请求就差很少了,若是每秒请求到 5k 的话,可能就直接把 MySQL 给打死了,致使系统崩溃,用户也就无法再使用系统了。可是高峰期一过,到了下午的时候,就成了低峰期,可能也就 1w 的用户同时在网站上操做,每秒中的请求数量可能也就 50 个请求,对整个系统几乎没有任何的压力。blog

  若是使用 MQ,每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求,由于 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过本身每秒能处理的最大请求数量就 ok,这样下来,哪怕是高峰期的时候,A 系统也绝对不会挂掉。而 MQ 每秒钟 5k 个请求进来,就 2k 个请求出去,结果就致使在中午高峰期(1 个小时),可能有几十万甚至几百万的请求积压在 MQ 中。

  这个短暂的高峰期积压是 ok 的,由于高峰期过了以后,每秒钟就 50 个请求进 MQ,可是 A 系统依然会按照每秒 2k 个请求的速度在处理。因此说,只要高峰期一过,A 系统就会快速将积压的消息给解决掉。

消息队列的缺点

  上面吹了消息队列的一堆优势,可是也不能不知道使用它带来的一些缺点吧!缺点有如下几点:

  • 系统可用性下降
    系统引入的外部依赖越多,越容易挂掉。原本你就是 A 系统调用 BCD 三个系统的接口就行了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套系统崩溃的,你不就完了?

  • 系统复杂度提升
    硬生生加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失状况?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。

  • 一致性问题
    A 系统处理完了直接返回成功了,人都觉得你这个请求就成功了;可是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

  因此消息队列实际是一种很是复杂的架构,你引入它有不少好处,可是也得针对它带来的坏处作各类额外的技术方案和架构来规避掉,作好以后,你会发现,妈呀,系统复杂度提高了一个数量级,也许是复杂了 10 倍。可是关键时刻,用,仍是得用的。

几个消息队列的比较

综上,各类对比以后,有以下建议:

通常的业务系统要引入 MQ,最先你们都用 ActiveMQ,可是如今确实你们用的很少了,没通过大规模吞吐量场景的验证,社区也不是很活跃,因此你们仍是算了吧,我我的不推荐用这个了;

后来你们开始用 RabbitMQ,可是确实 erlang 语言阻止了大量的 Java 工程师去深刻研究和掌控它,对公司而言,几乎处于不可控的状态,可是确实人家是开源的,比较稳定的支持,活跃度也高;

不过如今确实愈来愈多的公司会去用 RocketMQ,确实很不错,毕竟是阿里出品,但社区可能有忽然黄掉的风险(目前 RocketMQ 已捐给 Apache,但 GitHub 上的活跃度其实不算高)对本身公司技术实力有绝对自信的,推荐用 RocketMQ,不然回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。

因此中小型公司,技术实力较为通常,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。

若是是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,况且几乎是全世界这个领域的事实性规范。

相关文章
相关标签/搜索