目录
消息队列(MQ)
基本概念
“消息队列”可理解为是在消息传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标过程中充当中间环节,队列的主要目的是提供路由并保证消息的传递。如果发送消息时接收者无响应,消息队列会保留消息再次发送。
消息队列可理解为是一个消息的链表。链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中指针链接的次序来实现的。
链表由一系列结点(链表中的每个元素称为一个“结点”)组成,结点可以在运行时动态生成。每个结点包含两个部分:一个是存储数据元素的数据域,一个是存储下一个结点地址的指针域。
消息队列的主要优点:异步处理、应用解耦、流量削峰。
消息队列的常用模式:
- Point-to-Point(P2P):点对点(生产者发送一条消息到队列,只有一个用户能收到这条消息)。
- Publish/Subscribe(Pub/Sub):发布/订阅(发送者发送到主题的信息,只有订阅了该主题的用户才会收到这条信息)。
消息队列的缺点及弥补方法:
- 系统稳定性降低:系统引入的外部依赖越多,越容易挂掉。因此为了降低因消息队列出问题导致整个系统几乎不可用的情况出现的概率,消息队列不应该是单机的。
- 系统复杂度提高了。因此要注意充分考虑相关的各种可能出现的问题,加大对系统维护的力度。
- 数据不一致问题。可通过分布式事务(将所有后续数据更新操作放在一个事务里,要么都成功,要么都失败)来解决这个数据不一致的问题。
消息中间件
消息队列中间件是分布式系统中重要的组件,能帮助实现高性能、高可用、可伸缩和最终一致性架构。
ActiveMQ
ActiveMQ是Apache下的一个开放源代码的消息中间件,它是一个纯Java程序,因此应用ActiveMQ需要操作系统支持Java虚拟机。
ActiveMQ消息形式:
- topic:不安全、无状态、一对多、数据易丢失、传输效率高。
- queue:安全、有状态、一对一、数据不易丢失、传输效率低。
RabbitMQ
RabbitMQ是实现了AMQP(高级消息队列协议)的开源消息代理软件,它是由Erlang语言编写的。Erlang语言是一种通用的面向并发的编程语言,掌握该语言的使用有一定的难度。
RabbitMQ比较依赖于内存,消息堆积过多时性能明显下降且不够稳定。
RabbitMQ支持多种客户端语言,管理界面较丰富。
RocketMQ
RocketMQ是一个消息中间件,借鉴了Kafka的设计思想,但不是Kafka的拷贝,它具有高吞吐量、高可用性、适用于大规模分布式系统的特点。
RocketMQ相比较RabbitMQ、Kafka的主要优势有:
- 支持事务型消息(保持消息发送和DB操作两方的最终一致性)。
- 支持结合RocketMQ的多个系统之间的数据最终一致性。
- 支持18个级别的延迟消息。
- 支持指定次数和时间间隔的失败消息重发(Kafka不支持,RabbitMQ需手动确认)。
- 支持消费者端标签过滤,减少不必要的网络传输。
- 支持重复消费。
Kafka
Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。
Kafka是运行在一个或多个服务器的集群(Cluster)上的,Kafka集群分类存储的记录流被称为主题(Topics)。
Kafka客户端和服务器端之间的通信是靠一个简单的、高性能的、与语言无关的TCP协议来完成的。这个协议有不同版本,并保持了向后兼容旧版本。
Kafka的消息队列模式一般分为两种:点对点模式,发布订阅模式。
Kafka的特性(设计原则):
- 高吞吐、低延迟。
- 高伸缩性。
- 持久性、可靠性。
- 容错性。
- 高并发。
Kafka的使用场景:
- 活动跟踪。
- 传递消息。
- 度量指标。
- 日志记录。
- 流式处理。
- 限流削峰。