持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
Kafka是基于Java开发的开源流平台,目前广泛用于日志的收集、消息的订阅与发布(即就是我们常说的消息队列),具有高吞吐、低延迟、可持久化等特性。本文内容主要分为以下几个模块:
-
基于Docker环境安装Kafka
-
Golang扩展模块(sarama)安装
-
基于Golang扩展模块(sarama)操作Kafka。
官方文档:kafka.apache.org/documentati…
kafka-go客户端文档:github.com/Shopify/sar…
安装
kafka使用了zookeeper作为它的注册中心,所以需要安装的模块主要有两个部分:kafka、zookeeper。仓库地址:hub.docker.com/r/bitnami/k…
1、编写docker-compose.yml文件
version: "3"
services:
zookeeper:
image: 'bitnami/zookeeper:latest'
ports:
- '2181:2181'
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
kafka:
image: 'bitnami/kafka:latest'
ports:
- '9092:9092'
- '9093:9093'
environment:
- KAFKA_BROKER_ID=1
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT
- KAFKA_CFG_LISTENERS=CLIENT://:9092,EXTERNAL://:9093
- KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka:9092,EXTERNAL://localhost:9093 # 外网访问时,需要修改为外网主机的IP地址
- KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
- KAFKA_CFG_INTER_BROKER_LISTENER_NAME=CLIENT
- ALLOW_PLAINTEXT_LISTENER=yes
depends_on:
- zookeeper
2、启动容器
docker-compose up -d
golang 模块安装
go get github.com/Shopify/sarama
基于golang 模块的基础使用
发送消息(生产者):
// 获取生产者接口,当为外网主机时修改localhost为主机IP地址
producer, err := sarama.NewSyncProducer([]string{"localhost:9093"}, nil)
if err != nil {
log.Fatal(err)
return
}
defer func() {
// 关闭生产者
if err = producer.Close(); err != nil {
log.Fatal(err)
return
}
}()
// 定义需要发送的消息
msg := &sarama.ProducerMessage{
Topic: "topic",
Key: sarama.StringEncoder("key"),
Value: sarama.StringEncoder("value"),
}
// 发送消息,并获取该消息的分片、偏移量
partition, offset, _ := producer.SendMessage(msg)
if err != nil {
log.Fatal(err)
return
}
fmt.Printf("partition:%d offset:%d\n", partition, offset)
接受消息(消费者):
// 获取消费者接口,当为外网主机时修改localhost为主机IP地址
consumer, err := sarama.NewConsumer([]string{"localhost:9093"}, sarama.NewConfig())
if err != nil {
fmt.Println(err)
return
}
defer func() {
// 关闭消费者
if err = consumer.Close(); err != nil {
fmt.Println(err)
return
}
}()
// 获取消费者的分片接口,sarama.OffsetNewest 标识获取新的消息
partitionConsumer, err := consumer.ConsumePartition("topic", 0, sarama.OffsetNewest)
if err != nil {
fmt.Println(err)
return
}
defer func() {
if err = partitionConsumer.Close(); err != nil {
fmt.Println(err)
return
}
}()
for msg := range partitionConsumer.Messages() {
fmt.Printf("分片:%d 偏移:%d Key:%s Value:%s\n", msg.Partition, msg.Offset, msg.Key, msg.Value)
}