SpringBoot - 消息队列 MQ
为什么要使用消息队列-MQ
不要跟风 使用 MQ 是为了:
- 解耦:
传统模式下系统间耦合性太强,比如系统 A 在代码中直接调用系统 B 和系统 C 的代码,如果将来 D 系统接入,系统 A 还需要修改代码,过于麻烦!
使用了 MQ 后系统 A 将消息写入消息队列,需要消息的系统 B、C、D 自己从消息队列中订阅,从而系统 A 不需要做任何修改。
- 异步:
传统模式下一些非必要的业务逻辑以同步的方式运行,太耗费时间!
使用了 MQ 后系统 A 将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度。
- 削峰:
传统模式下并发量大的时候,所有的请求直接连接到数据库,会造成数据库连接异常从而引起系统崩溃!
使用了 MQ 后系统 A 慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息,减少后端的压力。在生产中,这个短暂的高峰期积压是允许的。
不要挖坑 不管是引入 MQ 技术,还是其他技术,有利也有弊:
- 系统可用性降低: 引入 MQ 之后一旦 MQ 不可用之后(提供 MQ 的服务挂掉了),那凡是关联使用的系统都会受到影响,因此,系统可用性降低
- 系统复杂性增加: 要多考虑很多方面的问题,比如一致性问题、如何保证消息不被重复消费,如何保证保证消息可靠传输等等,会使得系统的复杂性增大(可能会引入一些潜在的 bug)
个人建议,要看实际项目的需求,业务量不是特别大的项目,不建议为了使用而使用。
当然如果项目中有以上的场景需求,或者使用传统模式时遇到了瓶颈时,大胆的引入吧(上面说的弊端也是有很多解决方案的,如可以搭建 MQ 集群来保持 MQ 的高可用性)!
使用哪种方案
目前常见和使用广泛的 MQ 有 ActiveMQ、RabbitMQ、RocketMQ、Kakfa,至于使用哪个方案,还是要看使用场景的(公司规模、使用的语言、数据量等)
ActiveMQ
- ActiveMQ 5 “Classic”: 实际上 ActiveMQ Classic 原来就叫 ActiveMQ,是 Apache 开发的基于 JMS 1.1 的消息服务器,目前稳定版本号是 5.x
- ActiveMQ Artemis: ActiveMQ Artemis 是由 RedHat 捐赠的 HornetQ 服务器代码的基础上开发的,目前稳定版本号是 2.x。
和 ActiveMQ Classic 相比,Artemis 版的代码与 Classic 完全不同,并且,它支持 JMS 2.0,使用基于 Netty 的异步 IO,大大提升了性能。
此外,Artemis 不仅提供了 JMS 接口,它还提供了 AMQP 接口,STOMP 接口和物联网使用的 MQTT 接口。
官网上有这么一句话:
There are currently two “flavors” of ActiveMQ available - the “classic” 5.x broker and the “next generation” Artemis broker. Once Artemis reaches a sufficient level of feature parity with the 5.x code-base it will become ActiveMQ 6. Initial migration documentation is available.
翻译过来就是目前有两种“风格”的 ActiveMQ 可用-“经典”5.x 代理和“下一代”Artemis 代理。一旦 Artemis 与 5.x 代码基达到足够的特性奇偶校验级别,它将成为 ActiveMQ6。
可以看到 ActiveMQ 目前属于转型期,如果是新项目的话,还是期待下 ActiveMQ6 的发布吧。
RabbitMQ
RabbitMQ 是一个由 Erlang 语言开发的基于 AMQP 标准的开源实现,而 Erlang 语言天生具备高并发的特性,虽然懂的 erlang 的开发人员不多,无法进行定制化,
但 RabbitMQ 的社区十分活跃,可以解决开发过程中遇到的常见问题,而且提供的管理界面用起来十分方便,这对于中小型公司来说十分重要。
Kafka
kafka 是最初由 Linkedin 公司开发,是一个分布式、分区的、多副本的、多订阅者,基于 zookeeper 协调的分布式日志系统(也可以当做 MQ 系统),
常见可以用于 web/nginx 日志、访问日志,消息服务等等,Linkedin 于 2010 年贡献给了 Apache 基金会并成为顶级开源项目。
如果是大数据领域或者有日志采集功能的,肯定是首选 kafka
RocketMQ
当然如果项目使用了阿里云的全家桶,可以试试阿里出品的 RocketMQ (当然在 2016 年底已经贡献给了 Apache,成为了 Apache 的一个顶级项目)
RocketMQ 中文资料丰富,也得到了阿里各个系统的验证,对于一般的项目来说,直接拿来就可以用。
而且针对 rocketMQ,大型软件公司也可以抽出人手对 rocketMQ 进行定制化开发,毕竟国内有能力改 JAVA 源码的人,还是相当多的。
Redis
最后补充一个 Redis ,虽然它是一个 Key-Value 数据库存储系统,但它本身支持 MQ 功能,所以完全可以当做一个轻量级的队列服务来使用。
对于 RabbitMQ 和 Redis 的入队和出队操作,各执行 100 万次,每 10 万次记录一次执行时间。测试数据分为 128Bytes、512Bytes、1K 和 10K 四个不同大小的数据。
实验表明:
- 入队时,当数据比较小时 Redis 的性能要高于 RabbitMQ,而如果数据大小超过了 10K,Redis 则慢的无法忍受;
- 出队时,无论数据大小,Redis 都表现出非常好的性能,而 RabbitMQ 的出队性能则远低于 Redis。
当项目中已经引入了 Redis 且数据量和并发量(其实一般公司的项目,并不会太大) 不是非常大的话,也可以直接利用 Redis 的 MQ 功能来作为消息队列的中间件
总结
其实各个方案都有其优点和使用场景:
- ActiveMQ Artemis:支持协议较多,所以项目需要支持不同语言不同协议(例如与物联网相关系统交互的 MQTT 协议) 项目的消息队列,优先选用
- RabbitMQ:官方提供管理页面,可以较简单的管理重复消息,所以如果没有定制化的需求,且吞吐量要求不是那么高(单机吞吐量万级以上) 的,优先选用
- RocketMQ: 阿里出品,如果会用到 顺序消息、事务消息等 ,或者项目部署在阿里云中,使用了其他的阿里云的产品,不妨直接试试 RocketMQ
- Redis: 如果不想引入新的中间件(当然有利有弊,一旦挂了则缓存+消息队列都不可用了),且对数据量要求不那么大的话,可以采用
- Kafka: 基本上日志收集、消息系统、活动追踪、运营指标、流式处理、时间源等都是用 kafka,阿里云、腾讯云都推出了 Kafka 的云服务,可直接在云服务商直接开通使用
关于部署,日常开发中建议直接使用 docker 安装,线上的话如果资金到位建议使用云服务提供的 MQ 服务,能省去不少事情(尤其是维护成本)
如何保证可靠性
- 如何保证消息队列是高可用的?
- 如何保证消息不被重复消费?
- 如何保证消费的可靠性传输?
- 如何保证消息的顺序性? 推荐 RocketMQ
- 如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时怎么解决?
消息队列常见问题和解决方案消息队列常见问题和解决方案 这篇文章写的不错,暂且收藏了
不过在尝试解决这些问题时有必要明白一点,其实小公司业务量不大,并发量不高的情况下这些问题是几乎不会发生的……
即使偶尔出现,开发人员手动修复数据处理就好。所以可结合公司实际业务场景看有没有必要解决这些问题。
不过对于技术人员来说,还是有必要了解一下。
RabbitMQ 的三种类型的交换器
RabbitMQ 使用 Exchange(交换机) 和 Queue(队列) 来实现消息队列
广播式交换器类型 (Fanout)
该类交换器不分析所接收到消息中的 Routing Key,默认将消息转发到所有与该交换器绑定的队列中去
直接式交换器类型 (Direct)
该类交换器需要精确匹配 Routing Key 与 Binding Key,如消息的 Routing Key = Cloud,那么该条消息只能被转发至 Binding Key = Cloud 的消息队列中去
主题式交换器 (Topic Exchange)
该类交换器通过消息的 Routing Key 与 Binding Key 的模式匹配,将消息转发至所有符合绑定规则的队列中。
Binding Key 支持通配符,其中 * 匹配一个词组,# 匹配多个词组(包括零个)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论