前言
在我们开发过程中,有一些业务功能比较耗时,但是又不是很重要的核心功能,最典型的场景就是注册用户以后发送激活邮件分为两步
1:向数据库插入一条数据
2:向注册用户发送邮件
第2步其实并不是核心功能,但是发邮件比插入一条数据会更耗时,这种情况下我们可以把这个业务功能用异步处理,而异步处理的手段其中就包含了消费中间件,Kafka就是其中一个,消息中间件除了异步以外常用的功能就是:系统解耦、流量削峰等等
Kafka入门
官网地址:https://kafka.apache.org
下面我们就先把Kafka跑起来,我这里用的是3.1.0版本的
安装
首先,kafka依赖jdk和zookeeper,这里就不演示这两个的安装,请自行安装,其实也很简单
zookeeper下载地址: https://zookeeper.apache.org/releases.html
然后启动你的本地zookeeper
下载地址:https://kafka.apache.org/downloads
下载完上传到服务器上,如下
首先进行解压,解压命令为
tar -zxvf kafka_2.13-3.1.0.tgz
其次,修改config/server.properties的信息,主要是下面的信息
broker.id=0 #broker就是kafka服务器,每天kafka服务器的id唯一即可
listeners = PLAINTEXT://192.168.0.90:9092 #对外暴漏的访问端口
log.dirs=/tmp/kafka-logs #kafka日志位置
zookeeper.connect=192.168.0.90:2181 # zookeeper的连接地址
zookeeper.connection.timeout.ms=18000 #zookeeper连接超时时间
更多配置请参考:https://kafka.apache.org/documentation/#brokerconfigs
修改完就可以启动了,启动命令如下
./bin/kafka-server-start.sh -daemon config/server.properties
-daemon表示后台运行,config/server.properties配置文件地址
cat logs/server.log 查看服务启动日志,如下就表示成功了
使用
首先我们需要创建一个Topic,这是kafka的一个概念,它是一个逻辑概念,并不存储真正的数据,你可以理解为就是队列的名字
./bin/kafka-topics.sh --help #查看帮助文档
./bin/kafka-topics.sh --bootstrap-server=192.168.0.90:9092 --list #查看topic列表
刚开始查看肯定是空的,因为你刚安装,如下
创建一个名为zxc1的topic,创建完查看,命令如下
bin/kafka-topics.sh --create --bootstrap-server=192.168.0.90:9092 --topic zxc1
使用kafka提供的脚本启动一个生产者,也就是用来往zxc1发送消息的,命令如下
./bin/kafka-console-producer.sh --bootstrap-server=192.168.0.90:9092 --topic zxc1
启动完输入没报错就是成功了,如下
然后,在另外的窗口启动一个消费者,命令如下
./bin/kafka-console-consumer.sh --bootstrap-server 192.168.0.90:9092 --topic zxc1
然后你在生产端再发送一条消息,然后再查看控制台,如下
这样一个简单的生产->消费模式就完成了
使用进阶
你可能有个好奇的问题,为啥zxc1-test和zxc2-test消息没有消费到,因为默认情况下kafka的消费者启动消费消息是从启动时候计算的,如果你要从头开始拉取,那需要添加参数--from-beginning,如下
./bin/kafka-console-consumer.sh --bootstrap-server 192.168.0.90:9092 --from-beginning --topic zxc1
至于其他使用,都可以通过--help的形式进行查看,获取直接去官网查看
./bin/kafka-console-consumer.sh --help
单播消息
首先需要介绍一个消费者组的概念,消费者组也是一个逻辑概念,它下面可以有多个消费者,单播消息是指有多个消费者在同一个消费者组监听的情况,下面就来演示下你就明白了,首先看下现在消费者组列表有哪些,现在肯定是没有消费者组的,如下
./bin/kafka-consumer-groups.sh --bootstrap-server=192.168.0.90:9092 --list
然后我们启动两个consumer运行在zxcgGroup-1组监听zxc1的消息,如下,注意,是两个哦
./bin/kafka-console-consumer.sh --consumer-property group.id=zxcGroup-1 --bootstrap-server 192.168.0.90:9092 --topic zxc1
--consumer-property group.id=zxcGroup-1 代表消费者在消费者组zxcGroup-1进行监听
然后我们在客户端发送消息,如下
这就是单播消费,同一个组只会有一个消费者拿到消息,你可以多试几下
此时:如果把第一个消息者关闭掉,然后再发消息,那么kafka会把消息自动转给第二个消费者,如下
再看下消费者组列表,现在就有信息了,如下
多播消息
那么如果我们要两个客户端同时消费到消息呢?很简单,我们只需要启动另一个消费者在不同的消费者组监听就行了,如下是两个相关的命令与监听情况
./bin/kafka-console-consumer.sh --consumer-property group.id=zxcGroup-1 --bootstrap-server 192.168.0.90:9092 --topic zxc1
./bin/kafka-console-consumer.sh --consumer-property group.id=zxcGroup-2 --bootstrap-server 192.168.0.90:9092 --topic zxc1
这个时候,我们再发送一条消息zxc6-test,情况如下
这样便实现了消息的多播,是不是很简单
同时我们还可以通过以下命令查看消费者组的消费情况
./bin/kafka-consumer-groups.sh --bootstrap-server 192.168.0.90:9092 --describe --group zxcGroup-1
current-offset:当前消费组的已消费偏移量,也就是消费到哪了
log-end-offset:主题对应分区消息的结束偏移量(HW),简单理解为有多少条消息
lag:当前消费组未消费的消息数
核心概念
说明快速的进行了kafka的使用,下面就来说一下具体的概念,说之前写来看张单机的架构图,如下
下面一个个进行解释,只要你理解了这些概念,对理解kafka就很容易了
Broker
Kafka节点的特殊叫法,简单理解就是部署了kafka并启动的服务器
Topic
kafka主题,注意这只是一个逻辑概念,它并不存存储数据,你可以理解同个队列的一个激活,需要结合分区理解
Partition
真正存储数据的,是Topic下面的一个数据,这才是kafka真正的队列,一个topic有多个Partition
这样设计的原因主要是考虑数据多的时候如果真有一个队列那性能会很差,多个可以降低这种问题
Producer
消息的发送者,负责发送消息的,在kafka中producer没有组的概念,它负责把消息发到指定的topic中某个Partition中
ConsumerGroup
Consumer的一个集合,也是一个逻辑概念,kafka消费信息是以ConsumerGroup为单位的,ConsumerGroup可以用来实现多播功能
Consumer
ConsumerGroup中真正消费信息的Consumer
这里再补一张图,如下
topic分区
我们之前创建topic的时候,没有任何指定,默认只有一个分区,也就是0分区,可以通过以下命令进行查看
./bin/kafka-topics.sh --describe --bootstrap-server=192.168.0.90:9092 --topic zxc1
我们可以使用下面的命令创建多个分区,如下
./bin/kafka-topics.sh --create --bootstrap-server=192.168.0.90:9092 --partitions 2 --topic zxc2
再查看下zxc2的情况,如下
日志存储
kafka日志存储在config/server.properties的log.dirs路径中,我们看看下面的内容是啥,如下
可以看到我们zxc1-0有一个文件夹,zxc2有0和1两个文件夹,也就是说几个分区就有多少个文件夹
默认情况下kafka的日志存储7天,在config/server.properties文件的log.retention.hours中
补充
最后再补一个概念,副本,副本其实很容易理解,就是对分区的一个备份,做数据备份的,如图所示
总结
kafka的使用并不难,关键是要理解它的核心概念,如果理解了这些基本上在使用上就不会有啥疑问,至于一些其他设计细节,这里只是稍微提了一句,后面有时间再说