什么是消息队列?
就是一个先进先出的存放消息的队列,所以消费消息时也是按照顺序来消费的。
参与消息传递的双方称为 生产者 和 消费者 ,生产者负责发送消息,消费者负责处理消息。
我们知道操作系统中的进程通信的一种很重要的方式就是消息队列。
我们这里提到的消息队列稍微有点区别,更多指的是各个服务以及系统内部各个组件/模块之前的通信,属于一种 中间件 。
中间件:一类为应用软件服务的软件,应用软件是为用户服务的,用户不会接触或者使用到中间件。https://www.zhihu.com/question/19730582/answer/1663627873
消息队列有什么用?
通常来说,使用消息队列主要能为我们的系统带来下面三点好处:
通过异步处理提高系统性能(减少响应所需时间)
- 将用户的请求数据存储到消息队列之后就立即返回结果。随后,系统再对消息进行消费。
- 最常见的是订单,用户提交之后,不能立即返回订单提交成功(后续流程较为复杂),失败或者成功通过邮件等异步通知。(如火车票、电影票)
削峰/限流
- 将短时间高并发产生的事务消息存储在消息队列中,后端服务慢慢消费,避免直接被打垮
降低系统耦合性
- 每个模块只需要负责自己的功能模块的实现,剩余的操作,将请求作为消息丢掉下一个模块进行消费即可,不需要管其他模块的具体实现,专注于自己即可
- 例如,我们商城系统分为用户、订单、财务、仓储、消息通知、物流、风控等多个服务。用户在完成下单后,需要调用财务(扣款)、仓储(库存管理)、物流(发货)、消息通知(通知用户发货)、风控(风险评估)等服务。使用消息队列后,下单操作和后续的扣款、发货、通知等操作就解耦了,下单完成发送一个消息到消息队列,需要用到的地方去订阅这个消息进行消息即可。
实现分布式事务
- RocketMQ、 Kafka、Pulsar、QMQ 都提供了事务相关的功能。事务允许事件流应用将消费,处理,生产消息整个过程定义为一个原子操作。
顺序保证
- RocketMQ、RabbitMQ、Pulsar、Kafka,都支持顺序消息,适用于那些对数据顺序有严格要求的场景
延时/定时处理
- 消息发送后不会立即被消费,而是指定一个时间,到时间后再消费。大部分消息队列,例如 RocketMQ、RabbitMQ、Pulsar、Kafka,都支持定时/延时消息。
数据流处理
- 针对分布式系统产生的海量数据流,如业务日志、监控数据、用户行为等,消息队列可以实时或批量收集这些数据,并将其导入到大数据处理引擎中,实现高效的数据流管理和处理。
如果在面试的时候你被面试官问到这个问题的话,一般情况是你在你的简历上涉及到消息队列这方面的内容,这个时候推荐你结合你自己的项目来回答。
使用消息队列会带来哪些问题?
- 系统可用性降低:消息可能会丢失或者消息队列挂掉
- 系统复杂性提高: 需要克服消息丢失、重复消费、消费顺序混乱等问题
- 一致性问题: 需要保证消息正确消费。
RPC 和消息队列的区别
从用途来看:
- RPC :解决两个服务的远程通信问题,这个过程就像调用本地方法一样简单。
- 消息队列:降低系统耦合性、实现任务异步、有效地进行流量削峰。
从通信方式来看:
- RPC :双向直接网络通讯
- 消息队列:单向引入中间载体的网络通讯。
从架构上来看:
- 消息队列:需要把消息存储起来
- RPC :直接网络通讯,不用存储。
从请求处理的时效性来看:
- RPC:一般会立即被处理
- 消息队列:并不一定会立即被处理。
分布式消息队列技术选型
常见的消息队列都支持持久化到磁盘。
比对
语言
- Kafka:采用Scala语言开发
- RabbitMQ:由Erlang语言开发(定制比较麻烦),但是比较适用于高并发,且延时较低(语言特性)
- RocketMQ:采用Java语言开发(定制比较容易)
性能和可靠性
- Kafka:吞吐量极高,使用了零拷贝
- TPS可达百万条/秒
- 支持同步和异步复制消息,但异步复制存在丢消息的可能。
- 采用分布式架构,一个数据多个副本
- 可能处在重复消费的问题(在大数据或者日志领域可以忽略)
- RocketMQ:性能较高
- 单机写入TPS单实例约7万条/秒
- 采用分布式架构
- 支持强一致性
- RabbitMQ:性能稍逊于Kafka和RocketMQ
- 可靠性较好,支持确认机制、事务、委托和备份交换器等机制。
- 采用主从架构
- 数据丢失的概率最低
一个内存队列:Spring Boot + Disruptor 实战入门
