Kafka 单机使用案例(本地开发、服务器运行皆可用)

5,038 阅读7分钟

最近由于业务需要,需要用到消息引擎。

在参考这篇文章——消息中间件部署及比较:rabbitMQ、activeMQ、zeroMQ、rocketMQ、Kafka、redis 之后,选定了 Kafka。

本篇文章涉及到的主要内容:

  1. Kafka 安装到 CentOS 7.4
  2. Kafka 单机配置、启动和测试生产消费
  3. 本地开发环境编码实现生产消费
  4. 部署到服务器运行
  5. 总结

额外说明一下:

Kafka 版本为 2.3.0

本篇文章涉及到的案例仅仅涉及到生产者发送消息和消费者消费消息

Kafka 安装到 CentOS 7.4

参考官网的 Quickstart,安装主要步骤如下:

进入 /usr/local/ 目录(目录可以随意更改,个人习惯),下载安装文件并解压。参考下面命令:

cd /usr/local/

wget http://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.3.0/kafka_2.12-2.3.0.tgz

tar -zxvf kafka_2.12-2.3.0.tgz

到了这一步,安装就已经完成了。

是不是很简单?这里呢,可以把它理解成 Winows 系统里面免安装文件(只需要解压)。那要是想启动程序怎么办?点击可执行文件就行了。

相对应的,Kafka 2.3.0 在 CentOS 服务器里面也是同样的操作。

Kafka 单机配置、启动和测试生产消费

Kafka 2.3.0 提供了默认的配置,若仅仅是测试的话,不需要修改配置文件。

整个流程大致如下:

  1. 使用默认配置,启动服务
  2. 创建 topic (下面做介绍)
  3. 使用生产者发送消息
  4. 使用消费者接收并处理消息

上面提到的 topic、创建者、消费者可以这样理解:

假如你是一个男孩子,遇见了一个漂亮的女孩子,你想去搭讪,总得先找个话题吧。

你:嘿,小姐姐,地上的 100 块钱是你的么?

小姐姐:对,是我的。谢谢你哇。

结合上面的场景,topic 就是你对小姐姐的提问,产生了一个对话。生产者就是你自己,小姐姐作为消费者。小姐姐针对你的消息做出了回应就是消费消息。

当然,上面的逻辑并不严谨。更加合适的例子应该是微博上的话题功能。

你可以自己发布新话题(#某某话题#),也可以关注热门话题回帖。你能收到你关注的话题的帖子,你针对某个话题的回帖也会让关注这个话题的其他人接收到。话题对应的就是 topic,你和其他人即是生产者,也是消费者。

弄清楚上述三者的关系之后,我们继续。

首先是启动服务,由于 kafka 需要依赖 Zookeeper,所以启动 Kafka 之前要先启动 Zookeeper,这在 2.3.0 版本里面已经内置了。命令参考如下:

# 进入 Kafka 安装目录
cd /usr/local/kafka_2.12-2.3.0
# 启动 zookeeper 使用默认配置就行 => .sh 文件就是可执行文件 .properties 文件是配置文件
bin/zookeeper-server-start.sh config/zookeeper.properties
# 然后启动 Kafka 服务
bin/kafka-server-start.sh config/server.properties

如何确认服务是否启动完成呢?可以用 jps 命令查看是否有 Kafka

接下来,创建 topic,同样用命令执行:

# 创建 topic --bootstrap-server 表示服务地址 --partitions 表示分区数  --replication-factor 表示分区备份数 这里不做深入  --topic 表示话题名称
bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test
# 查看话题是否创建成功
bin/kafka-topics.sh --list --bootstrap-server localhost:9092

如果出现了刚刚上面的 topic 就表示创建成功,然后就可以搭讪小姐姐了。

# 使用生产者发送消息 --broker-list 表示发送的节点 参考上面的 --bootstrap-server  输入之后可以直接输入消息内容 回车就下一行
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test

比如我发送一条 how nice girl

然后用消费者去接收消息,新开一个窗口比较直观

# 接收消息  --from-beginning 表示从头开始
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning

然后我们就可以愉快的左右互搏了。左边窗口发送,右边窗口接收。类似这样:

到此为止,我们已经完成了 Kafka 服务启动,消息生产和消费测试。最后再看看 Zookeeper 和 Kafka 的配置文件吧。

Zookeeper 配置文件位置在上面已经知道了,打开之后发现就只有三行默认配置:

# 指定了临时数据存储目录
dataDir=/tmp/zookeeper
#暴露的默认端口
clientPort=2181
# 限制连接到ZooKeeper的客户端的数量
maxClientCnxns=0

然后是 Kafka 的配置,这个就有点多了,挑几个单机配置下比较重要的吧:

# 服务监听地址 一般用内网 ip   0.0.0.0 表示不限制
listeners=PLAINTEXT://0.0.0.0:9092
# 对外暴露的地址 通常用在需要对公网提供服务时需要设置,ip 也是公网ip
advertised.listeners=PLAINTEXT://ip:9092

上面的这两个配置比较重要,大概意思就是——内网连接服务的话,就只需要 listener 配置,要对公网提供服务就需要配置 advertied.listener。两者具体的区别请参考这个链接 kafka listeners 和 advertised.listeners 的应用

这里如果没配置好的话,可能会出现以下问题:

  • 服务器在公网,服务正常启动,服务端测试正常,本地测试连接不上服务
  • 服务器在公网,服务正常启动,服务端测试正常,修改本地 hosts 文件后本地测试正常,部署到服务器无法正常运行

本地开发环境编码实现生产消费

在本地开发之前,需要保证服务器上的 Zookeeeper 和 Kafka 服务端口都已经开放,针对上面的配置,需要开放的端口分别是 2181 和 9092。如果是阿里云之类的服务器,除了服务器本身的防火墙外,可能还需要修改安全组访问策略配置。

下面是一个简单的案例,使用了 Spring Boot 框架,thymeleaf 模板,spring-kafka 依赖 jar 包作为 Kafka 的客户端。具体代码请移步 Kafka 单机案例 Github,git clone 代码之后把服务的地址换成自己的服务就行。

简单说明下代码结构和逻辑:

# application.yml 项目配置文件如下 
# 主要是配置 Kafka 生产者和消费者
spring:
  resources:
    static-locations: classpath:/templates/
  thymeleaf:
    cache: false
    encoding: UTF-8

  # kafka 相关配置
  kafka:
    # 生产者
    producer:
      bootstrap-servers: 127.0.0.1:9092
      retries: 0
      # 16 kb
      batch-size: 16384
      # 1 mb
      buffer-memory: 1048576

    # 消费者
    consumer:
      bootstrap-servers: 127.0.0.1:9092
      group-id: test
      enable-auto-commit: true
      max-poll-records: 100
      auto-offset-reset: earliest

配置文件编写之后,需要创建生产者和开启消费监听,对应的代码在 /src/main/java/com.idiotalex/config

红框中分别就是用代码读取配置文件实现生产者和消费者创建。红框上面的 KafkaConsumer 就是监听 topic,有消息就输出,模拟消费。

发送消息放在了 servive 里面,主要逻辑是调用 Kafka Java 客户端的 KafkaTemplate 模板发送消息。

然后在 MessageController 里面去调用发送消息方法,同时还提供了一个 Html 页面,用作发送消息的入口。一旦页面输入消息内容,点击发送,就会请求 MessageeController 发送消息,然后在 Kafka 消息监听方法里面输出来。

接下来就是部署到服务器上运行了。

部署到服务器运行

正常来说,跑通了本地环境,服务器也就没啥问题了。一旦发现部署到服务器上不可用,就要好好确认下本地环境和服务器环境的区,但总的来说,问题大多出在配置上面:

  • Kafka 服务或者 Zookeeper 服务挂掉
  • 对应端口没开放(可以用 Kafka tool 或者 ping 命令测试)
  • 配置文件有问题,主要是内外网的配置——也就是上面的 Kafka server.properties 中的 listener 和 advertised.listener 区别
  • 注意版本号,本文章是 Kafka-2.3.0 (不同版本的配置或者安装有些区别)

弄清楚了这些,应该问题都可以解决了。

总结

最后,这篇文章从 Kafka 的安装,到单机配置、服务端测试,再到 Java 客户端代码实现,最后部署可能出现的问题都做了大致的描述;另外一个,倘若开发过程中遇到问题,可以尝试开启 DEBUG 级别的日志,对排除错误会很有帮助。

希望能对大家有所帮助。