1. 什么是消息队列
- 消息队列(message queue),是一种应用程序的通信方法;
- 消息队列是 生产者-消费者 模型的典型代表,一端不断的网消息队列写数据,另一端不断地读数据;
- 消息队列中间件是分布式系统的重要组件,主要解决 解耦、异步消息、流量削峰 等问题,实现高性能、高可用、可扩展、和一致性问题;
- 消息队列作擅长于解决 多系统、异构系统 间的数据交换(消息通知/通讯)问题,你也可以把它用于系统间服务的相互调用(RPC);
2. 消息队列的特点
- 默认先进先出;
3. 消息发送流程
3.1. 同步发送
- 同步发送是指消息发送方发出数据后,会在收到接收方发回响应之后才发下一个数据包的通讯方式;
-
应用场景:此种方式应用场景非常广泛,例如重要通知邮件、报名短信通知、营销短信系统等。
3.2. 异步发送
- 异步发送指发送之后,指定回调函数,之后立即返回,发送结果在回调任务中处理(新线程)。
3.3. 单向发送
- 单向发送指发送者单向向服务器发送消息,只管发,不关心消息是否成功发送。
4. 消息队列应用场景
- 解耦;
- 异步;
- 削峰(负载均衡);
- 日志;
- 消息事务;
- 作业调度;
5. 常见的消息队列
- ActiveMQ
-- 具有丰富的API、多种集群构建模式,简单易用。但性能稍差,在面对高并发的情况下,会出现消息阻塞、堆积、延迟等问题; - RabbitMQ
-- RabbitMQ 有 ACK 确认机制,支持消息事务、支持 TTL、死信队列、延迟队列,同时支持 push / pull 模式,缺点是忽视消费端的消费能力,可能导致消费端能力饱和;
Consumer 两种消费模型:
- push
-- 定义:Broker 里面只要有消息就 推送 给消费端;
-- 优势:消费的实时性高;
-- 劣势:没有考虑消费端的消费能力,容易压垮 consumer;- pull
-- 定义:Consumer 通过 轮询 的方式询问 Broker 里面是否有消息,如果有消息就 拉取 到消费端;
-- 优势:在于可控制消费速度和消费数量保证不会超饱和;
-- 劣势:如果没有数据会出现空轮询消耗 CPU,尽管通过长轮询可以一定程度上缓解吗,但并未根本解决空轮询问题;
- Kafka
-- 基于 pull 的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。新版本支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。能够支持廉价的服务器上以每秒100k条数据的吞吐量。同时由于有 ack 机制,可以保证不丢失,但不能保证不重复; - RocketMQ
-- RocketMQ 是阿里开源的消息中间件,目前也已经孵化为Apache顶级项目,它是纯Java开发,具有高吞吐量、高可靠性、适合大规模分布式系统应用的特点。RocketMQ 思路起源于 Kafka,不过它对消息的可靠传输以及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binlog分发等场景;