【后端】消息队列入门(kafka)

65 阅读3分钟

了解一个新事物最好的办法是从为什么要有它的角度去了解,对于消息队列而言,我们之所以需要它是因为它有着三大特性。解耦,异步,削峰填谷。

特性

解耦

解耦的意思是尽可能降低系统与系统之间的联系,从而达到让系统的可拓展性变得更强。举例,假如你负责维护一个系统叫系统 A。目前,只有系统 B 需要 A 在完成一个操作后通知它。所以你只需要让 B 提供一个接口 /b,你把数据通过 /b 接口发送给 B 就可以了。假如后续又加入了系统 C 和系统 D,如果你不用消息队列,你还需要让 C 和 D 都出新接口。而且,对方不一定非得按照 B 的规则设计新接口,因此,除了添加额外的发送请求逻辑,你这边发送的数据还要做适配。

但是,有了消息队列,我们就不需要关注新系统接入进来这件事。我们只需要把消息往队列里面放,如果新系统需要,你们自己订阅相关主题,去拿你们想要的数据就够了。对于新接入的系统,系统 A 一侧并不需要添加额外的逻辑。这就是解耦带来的便利。

异步

这个异步是指对用户而言的。如果 client 端发送一个请求,这个请求需要 server 把所有耗时操作都做完,再返回结果,这个叫同步;而异步指的是,server 可以把关键操作做完,直接返回结果。而在消息队列的语境下,异步的意思就是把消息直接放到消息队列里。

我们还拿上一个例子举例。如果网页给你的系统 A 发送了一个请求,在没有消息队列前,你需要先发送请求给 B,B 花了一段时间响应,拿到结果后,然后才能返回给用户;假如引入了消息队列,你可以直接把消息放到消息队列里就直接返回结果。假如 B 的响应是一个长耗时操作,那么,第一个方案的用户体验会更好。

削峰填谷

很多时候上游产出数据的速度是很快的。下游不能都及时处理。比如系统 A 在高峰时间段产出消息的速度是 10MB/s,而下游的处理能力只有 1MB 每秒,如果没有消息队列,在高峰时间段,下游来不及响应这么多数据,会造成数据的丢失。

而有了消息队列,它可以充当高峰时的缓冲,比如,高峰时间持续了 100s,产生 1000MB 的数据,下游可以及时响应 100M,有 900M 存在于队列里。高峰结束后,下游可以慢慢悠悠的处理队列里这 900 MB 的数据。

Kafka 安装和运行实战

实验设备和工具

mac brew

安装步骤

brew install zookeeper
brew install kafka

注意 mac 使用 brew 安装的安装目录是比较奇怪的,bin 和 config 不在一块

zookeeper

bin: /usr/local/Cellar/zookeeper/3.9.0
config: /usr/local/etc/zookeeper

当然你需要替换成你自己的版本号

kafka

bin: /usr/local/Cellar/kafka/3.5.1
config: /usr/local/etc/kafka

修改 kafka 的配置文件 server.properties

listeners=PLAINTEXT://localhost:9092
advertised.listeners=PLAINTEXT://localhost:9092

网上有人说启动 zookeeper 和 kafka 直接用

brew services start zookeeper
brew services start kafka

就可以了,但实际这么启动的时候会报错,我使用下面的方式启动的:

启动 zookeeper
zookeeper-server-start /usr/local/etc/kafka/zookeeper.properties 
启动 kafka
kafka-server-start /usr/local/etc/kafka/server.properties

建立一个叫 test 的 topic

kafka-topics  --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test

建立一个生产者

kafka-console-producer --broker-list localhost:9092 --topic test

image.png

建立一个消费者

kafka-console-consumer --bootstrap-server localhost:9092 --topic test

image.png

未完待续