消息队列的流派
MQ 是什么
Message Queue(MQ)是一种消息队列中间件。MQ 的主要作用是通过分离消息的发送和接收来实现应用程序的异步和解耦。然而,MQ 的核心目的是通信:它屏蔽了底层复杂的通信协议,并定义了一套更简单的应用层通信协议。
在分布式系统中,模块间通信通常使用 HTTP 或自定义的 RPC TCP。这两种协议都较为原始,HTTP 难以实现双向通信,而 TCP 更加基础。MQ 在这些协议之上构建了一个简单的"协议"——生产者/消费者模型。MQ 提供的不是具体的通信协议,而是更高层次的通信模型。它定义了两个角色——生产者(发送数据)和消费者(接收数据),并提供 SDK 让我们能定义自己的生产者和消费者,实现消息通信而无需关注底层通信协议。
有 Broker 的 MQ
这类 MQ 通常有一台服务器作为 Broker,所有消息都通过它中转。生产者将消息发送给 Broker 后就完成了自己的任务,Broker 则负责将消息主动推送给消费者(或由消费者主动轮询)。
带 Topic 的 MQ
Kafka 和 JMS(如 ActiveMQ)属于这一类。生产者发送 key 和数据到 Broker,Broker 根据 key 决定将消息发送给哪个消费者。这是最常见的模式,也是我们对 MQ 最普遍的印象。在这种模式下,topic 通常是一个较大的概念,有时一个系统中可能只有一个 topic。topic 在某种程度上等同于 queue,生产者发送 key 就相当于说:“嘿,把数据放到这个 key 对应的队列中”。
如上所述,Broker 定义了三个队列:key1、key2、key3。生产者发送数据时会附带 key(如 key1)和实际数据,Broker 在推送数据时可能只推送数据本身,也可能连同 key 一起推送。尽管架构相似,Kafka 的性能远超 JMS。因此,这类 MQ 中 Kafka 几乎是唯一的选择。如果你需要一个高性能的数据流(注重性能而非灵活性),Kafka 是最佳选择。
轻量级 Topic
RabbitMQ(或更广泛地说,AMQP 协议)是这类 MQ 的代表。生产者发送 key 和数据,消费者定义订阅的队列,Broker 接收数据后通过特定逻辑将 key 映射到对应队列,然后将数据传递给队列。这种模式解耦了 key 和 queue。在这种架构中,queue 非常轻量(在 RabbitMQ 中,其上限取决于可用内存)。消费者只关心自己的 queue,生产者无需关心数据最终去向,只需指定 key。中间的映射层在 AMQP 中称为 exchange(交换机)。AMQP 定义了四种 exchange:
- 直接交换机:key 直接对应 queue。
- 扇形交换机:忽略 key,向所有 queue 发送消息副本。
- 主题交换机:key 可用通配符模糊匹配 queue。
- 头部交换机:忽略 key,根据消息的头部元数据决定发送到哪个 queue(AMQP 的头部元数据丰富且可自定义)。
这种架构为通信带来了极大的灵活性,几乎所有可以想到的通信方式都能通过这四种 exchange 实现。如果你需要一个灵活的企业数据总线,RabbitMQ 绝对值得考虑。
无 Broker 的 MQ
ZeroMQ 是无 Broker MQ 的代表。其作者敏锐地意识到 MQ 本质上是更高级的 Socket,旨在解决通信问题。因此,ZeroMQ 被设计成一个"库"而非中间件,实现了无 Broker 的目标。节点间的消息直接发送到彼此的队列中,每个节点既是生产者又是消费者。ZeroMQ 封装了一套类似 Socket 的 API,用于发送和接收数据。实际上,ZeroMQ 是一个跨语言的、功能强大的 Actor 模型邮箱库。你可以将自己的程序视为一个 Actor,ZeroMQ 则提供邮箱功能。它既可实现同一机器上的 RPC 通信,也能实现不同机器间的 TCP、UDP 通信。如果你需要强大、灵活、高效的通信能力,ZeroMQ 是不二之选。
一、Kafka介绍
Kafka是一个分布式、支持分区、多副本的消息系统,其最大特点是能实时处理大量数据以满足各种需求场景。它可用于日志收集、消息系统、用户活动跟踪和运营指标等。Kafka由Scala语言编写,于2010年贡献给Apache基金会并成为顶级开源项目。
1. Kafka的使用场景
- 日志收集
- 消息系统
- 用户活动跟踪
- 运营指标
2. Kafka基本概念
Kafka是一个分布式、分区的消息服务,提供了消息系统应有的功能。它借鉴了JMS规范的思想,但并未完全遵循JMS规范。JMS是类似于JDBC之于数据库的、针对Java调用消息队列的接口规范。
让我们先来了解一下基础的消息(Message)相关术语:
名称 | 解释 |
---|---|
Broker | 消息中间件处理节点,一个Kafka节点就是一个broker,一个或多个Broker可以组成一个Kafka集群 |
Topic | Kafka根据topic对消息进行归类,发布到Kafka集群的每条消息都需要指定一个topic |
Producer | 消息生产者,向Broker发送消息的客户端 |
Consumer | 消息消费者,从Broker读取消息的客户端 |
ConsumerGroup | 每个Consumer属于一个特定的Consumer Group,一条消息可以被多个不同的Consumer Group消费,但一个Consumer Group中只能有一个Consumer能够消费该消息 |
Partition | 物理上的概念,一个topic可以分为多个partition,每个partition内部消息是有序的 |
从较高层面来看,producer通过网络发送消息到Kafka集群,然后consumer进行消费,如下图所示:
服务端(brokers)和客户端(producer、consumer)之间通过TCP协议进行通信。
二、Kafka基本使用
官方文档
https://kafka.apache.org/documentation/
1. 安装
- 安装JDK
- 安装ZooKeeper
ZooKeeper主要服务于分布式系统,可用于:统一配置管理、统一命名服务、分布式锁和集群管理。分布式系统不可避免地面临节点管理问题(如实时感知节点状态、统一管理节点等),这些问题处理起来较为复杂。ZooKeeper作为一个通用中间件,能够有效解决这些问题。