1.1 发布与订阅消息系统
在正式讨论 ApacheKafka(以下简称Kafka)之前,先来了解什么是发布与订阅消息系统,以及为什么它是数据驱动型应用程序的关键组件。数据(消息)的发送者(发布者)不会直接把消息发送给接收者,这是发布与订阅消息系统的一个特点。发布者以某种方式对消息进行分类,接收者(订阅者)通过订阅它们来接收特定类型的消息。发布与订阅系统一般会有一个 broker,也就是发布消息的地方。
1.1.1 如何开始
发布与订阅消息系统的大部分应用场景是从一个简单的消息队列或进程间通道开始的。假设你的应用程序需要往其他地方发送监控信息,那么你就可以直接在这个应用程序和另一个可以在仪表盘上显示指标的应用程序之间建立连接,然后通过该连接推送指标,如图 1-1 所示。
图 1-1:单个直连的指标发布者
这是监控系统在刚开始时针对简单问题的解决方案。不久之后,你需要分析更长时间片段的指标,此时的仪表盘应用程序满足不了需求,于是,你启动了一个新的服务来接收指标。这个服务会把指标保存起来,用于后续的分析。与此同时,你修改了原来的应用程序,把指标同时发送到这两个仪表盘系统中。现在,你又多了 3 个可以生成指标的应用程序,它们都与这两个服务连接。你的同事建议你对这些服务进行轮询,这样就可以实现告警功能了。于是,你为每一个应用程序增加了用于发送指标的服务器。一段时间过后,更多的应用程序出于各自的目的,都从这些服务器获取指标。这时候的架构看起来如图 1-2 所示,节点之间的连接乱糟糟的,难以追踪。
图 1-2:多个直连的指标发布者
很显然,现在出现了技术债务,你决定先解决一些。于是,你创建了一个独立的应用程序,用于接收来自其他应用程序的指标,并为其他系统提供了一个查询服务器。这样,之前架构的复杂性就降低到了图 1-3 所示的样子。恭喜你,你已经创建了一个基于发布与订阅的消息系统。
图 1-3:指标发布与订阅系统
1.1.2 独立的队列系统
在你跟指标“打得不可开交”的时候,你的一位同事正在为日志消息忙得焦头烂额。还有一位同事正在跟踪网站用户的行为,为负责开发机器学习模型的同事提供用户活动数据,并为管理团队生成报告。你和同事们使用了同样的方式创建这些系统,将信息的发布者和订阅者解耦。图 1-4 所示的架构包含了 3 个独立的发布与订阅系统。
图 1-4:多个发布与订阅系统
这种方式比直接使用点对点连接(参见图 1-2)要好得多,但是它有太多重复的地方。你的公司因此要为数据队列维护多个系统,而每个系统又有各自的缺陷和不足。而且,接下来可能会有更多的场景需要用到消息系统。此时,你真正需要的是一个单一的集中式系统,它可以用来发布通用的数据,并且规模可以随着公司业务的增长而增长。