golang之操作kafka
安装第三方包:
go get github.com/IBM/sarama
生产者实例:
package main import (
"fmt"
"github.com/IBM/sarama"
) func main() { //1.生产者配置
config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForAll //ACK,发送完数据需要leader和follow都确认
config.Producer.Partitioner = sarama.NewRandomPartitioner //分区,新选出一个分区
config.Producer.Return.Successes = true //确认,成功交付的消息将在success channel返回 //2.连接Kafka client, err := sarama.NewSyncProducer([]string{"127.0.0.1:9092"}, config)
if err != nil {
fmt.Println("Producer error", err)
return
} defer client.Close() //3.封装消息 msg := &sarama.ProducerMessage{}
msg.Topic = "log"
msg.Value = sarama.StringEncoder("this is test log") //4.发送消息
pid, offset, err := client.SendMessage(msg) if err != nil {
fmt.Println("send faild", err)
}
fmt.Printf("pid:%v offset:%v\n", pid, offset)
}
消费者:
package main import (
"fmt" // "github.com/Shopify/sarama" // 该包已经转移到了IBM/sarama
"github.com/IBM/sarama"
) // kafka consumer func main() {
consumer, err := sarama.NewConsumer([]string{"127.0.0.1:9092"}, nil)
if err != nil {
fmt.Printf("fail to start consumer, err:%v\n", err)
return
}
partitionList, err := consumer.Partitions("web_log") // 根据topic取到所有的分区
if err != nil {
fmt.Printf("fail to get list of partition:err%v\n", err)
return
}
fmt.Println(partitionList)
for partition := range partitionList { // 遍历所有的分区
// 针对每个分区创建一个对应的分区消费者
pc, err := consumer.ConsumePartition("web_log", int32(partition), sarama.OffsetNewest)
if err != nil {
fmt.Printf("failed to start consumer for partition %d,err:%v\n", partition, err)
return
}
defer pc.AsyncClose()
// 异步从每个分区消费信息
go func(sarama.PartitionConsumer) {
for msg := range pc.Messages() {
fmt.Printf("Partition:%d Offset:%d Key:%v Value:%v", msg.Partition, msg.Offset, msg.Key, msg.Value)
}
}(pc)
}
}
完整文件内容:
package main import (
"context"
"fmt"
"github.com/IBM/sarama"
"log"
"math"
"os"
"os/signal"
"sync"
"syscall"
) // 更多参考:https://kpretty.tech/archives/gokafkaclient var addrs = []string{"172.29.97.140:9092"}
var topic = "log" func producer() {
// 生产者配置
config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForAll // ACK
config.Producer.Partitioner = sarama.NewRandomPartitioner // 分区
// 异步回调(两个channel, 分别是成功和错误)
config.Producer.Return.Successes = true // 确认
config.Producer.Return.Errors = true sarama.Logger = log.New(os.Stdout, "[Sarama]", log.LstdFlags) // 连接kafka
// 同步
client, err := sarama.NewSyncProducer(addrs, config)
// 异步
//client, err := sarama.NewAsyncProducer(addrs, config)
if err != nil {
fmt.Println("producer error", err)
return
} defer func() {
_ = client.Close()
}() // 封装消息
msg := &sarama.ProducerMessage{
Topic: topic,
Value: sarama.StringEncoder("this is test log"),
} pid, offset, err := client.SendMessage(msg)
if err != nil {
fmt.Println("send failed", err)
return
} fmt.Printf("pid:%v offset:%v \n", pid, offset)
} func consumer() {
consumer, err := sarama.NewConsumer(addrs, nil)
if err != nil {
fmt.Printf("fail to start consumer, err:%v \n", err)
return
}
partitionList, err := consumer.Partitions(topic) // 通过topic获取所有分区
if err != nil {
fmt.Printf("fail to get partition list, err:%v\n", err)
return
} fmt.Println(partitionList)
for partition := range partitionList { // 遍历所有分区
pc, err := consumer.ConsumePartition(topic, int32(partition), sarama.OffsetNewest)
if err != nil {
fmt.Printf("failed to start consumer for partition %d, err:%v\n", partition, err)
return
}
defer pc.AsyncClose()
go func(sarama.PartitionConsumer) {
for msg := range pc.Messages() {
// 当设置了key的时候,不为空
fmt.Printf("Partition:%d Offset:%d Key:%s Value:%s\n", msg.Partition, msg.Offset, string(msg.Key), string(msg.Value))
}
}(pc)
}
//time.Sleep(5 * time.Second)
select {}
} func groupConsumer() {
groupId := "sarama-consumer"
config := sarama.NewConfig()
// 关闭自动提交 和 初始化策略(oldest|newest)
config.Consumer.Offsets.AutoCommit.Enable = false
config.Consumer.Offsets.Initial = sarama.OffsetOldest
sarama.NewConsumerGroup(addrs, groupId, config)
} func main() {
// 生产者
//producer()
// 消费者(只能连续读取,中断期间会丢失数据)
//consumer() // 消费者
//groupConsumer()
SimpleConsumer()
} var groupID = "sarama-consumer"
var asyncOffset chan struct{}
var wg sync.WaitGroup const defaultOffsetChannelSize = math.MaxInt func SimpleConsumer() {
brokers := addrs
// 消费者配置
config := sarama.NewConfig()
// 关闭自动提交
config.Consumer.Offsets.AutoCommit.Enable = false
config.Consumer.Offsets.Initial = sarama.OffsetOldest
// 开启日志
logger := log.New(os.Stdout, "[Sarama] ", log.LstdFlags)
sarama.Logger = logger
consumer, err := sarama.NewConsumerGroup(brokers, groupID, config)
if err != nil {
panic(err)
}
defer func() { _ = consumer.Close() }()
// 搞一个上下文用于终止消费者
ctx, cancelFunc := context.WithCancel(context.Background())
// 监听终止信号
go func() {
logger.Println("monitor signal")
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
<-quit
logger.Println("stop consumer")
cancelFunc()
}()
// 消费数据
err = consumer.Consume(ctx, []string{topic}, &Consumer{})
if err != nil {
panic(err)
}
// 等待所有偏移量都提交完毕再退出
logger.Println("当前存在未提交的偏移量")
wg.Wait()
} type Consumer struct{} func (c *Consumer) Setup(session sarama.ConsumerGroupSession) error {
// 初始化异步提交的channel
asyncOffset = make(chan struct{}, defaultOffsetChannelSize)
wg.Add(1)
// 异步提交偏移量
go func() {
for range asyncOffset {
session.Commit()
}
wg.Done()
}()
return nil
} func (c *Consumer) Cleanup(_ sarama.ConsumerGroupSession) error {
// 关闭通道
close(asyncOffset)
return nil
} func (c *Consumer) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
EXIT:
for {
select {
case message := <-claim.Messages():
log.Printf("Message claimed: key= %s, value = %s, timestamp = %v, topic = %s", string(message.Key), string(message.Value), message.Timestamp, message.Topic)
// 标记消息,并不是提交偏移量
session.MarkMessage(message, "")
// 异步提交
asyncOffset <- struct{}{}
case <-session.Context().Done():
log.Println("cancel consumer")
break EXIT
}
}
return nil
}
更深入使用:
golang之操作kafka的更多相关文章
- Golang中如何正确的使用sarama包操作Kafka?
Golang中如何正确的使用sarama包操作Kafka? 一.背景 在一些业务系统中,模块之间通过引入Kafka解藕,拿IM举例(图来源): 用户A给B发送消息,msg_gateway收到消息后,投 ...
- Java操作Kafka
java操作kafka非常的简单,然后kafka也提供了很多缺省值,一般情况下我们不需要修改太多的参数就能使用.下面我贴出代码. pom.xml <dependency> <grou ...
- SparkStreaming操作Kafka
Kafka为一个分布式的消息队列,spark流操作kafka有两种方式: 一种是利用接收器(receiver)和kafaka的高层API实现. 一种是不利用接收器,直接用kafka底层的API来实现( ...
- kfka学习笔记一:使用Python操作Kafka
1.准备工作 使用python操作kafka目前比较常用的库是kafka-python库,但是在安装这个库的时候需要依赖setuptools库和six库,下面就要分别来下载这几个库 https://p ...
- Java操作Kafka执行不成功
使用kafka-clients操作kafka始终不成功,原因不清楚,下面贴出相关代码及配置,请懂得指点一下,谢谢! 环境及依赖 <dependency> <groupId>or ...
- go语言操作kafka
go语言操作kafka Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据,具有高性能.持久化.多副本备份.横向扩展等特点.本文介绍了如何使用Go语言发送和 ...
- 使用python操作kafka
使用python操作kafka目前比较常用的库是kafka-python库 安装kafka-python pip3 install kafka-python 生产者 producer_test.py ...
- C++操作Kafka使用Protobuf进行跨语言数据交互
C++操作Kafka使用Protobuf进行跨语言数据交互 Kafka 是一种分布式的,基于发布 / 订阅的消息系统.主要设计目标如下: 以时间复杂度为 O(1) 的方式提供消息持久化能力,即使对 T ...
- GO学习-(30) Go语言操作kafka
go操作kafka Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据,具有高性能.持久化.多副本备份.横向扩展等特点.本文介绍了如何使用Go语言发送和接收 ...
- kafka实战教程(python操作kafka),kafka配置文件详解
kafka实战教程(python操作kafka),kafka配置文件详解 应用往Kafka写数据的原因有很多:用户行为分析.日志存储.异步通信等.多样化的使用场景带来了多样化的需求:消息是否能丢失?是 ...
随机推荐
- LLM大模型基础知识学习总结
大家好,我是Edison. 在这个已经被AI大模型包围的时代,不了解一点大模型的基础知识和相关概念,可能出去聊天都接不上话.刚好近期我也一直在用GPT和GitHub Copilot,也刚好对这些基础知 ...
- 【Azure Policy】使用deployIfNotExists 把 Azure Activity logs 导出保存在Storage Account
问题描述 使用Azure Policy,对订阅下的全部Activity Log配置Diagnostic Setting,要求: 在Subscription或Management Group级别,针对未 ...
- git merge 详细操作,看完就懂
[root@hostname git_test]# git init hint: Using 'master' as the name for the initial branch. This def ...
- Ollama + JuiceFS:一次拉取,到处运行
今天这篇博客转载自我们的全栈工程师朱唯唯.在使用 Ollma 进行大模型加载时,她尝试使用了 JuiceFS 进行模型共享,JuiceFS 的数据预热和分布式缓存功能显著提升了加载效率,优化了性能瓶颈 ...
- 知识点考古:php5的面向对象学习笔记
闲来无事翻看以前收藏的资料,考古到保存的这篇文章对php的OOP的整理还很系统.原链接已经打不开(http://www.cublog.cn/u/17686/showart.php?id=146562) ...
- 痞子衡嵌入式:JLink命令行以及JFlash对于下载算法的作用地址范围认定
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是JLink命令行以及JFlash对于下载算法的作用地址范围认定. 最近痞子衡在给一个 RT1170 客户定制一个 Infineon Mi ...
- (九)Redis 哨兵机制与集群
主从复制中,如果从库发生故障了,客户端可以继续向主库或其他从库发送请求,但是如果主库发生故障了肿么办呢?读请求,那还可以由从库继续提供服务,写请求就么得办法了.此时,哨兵机制就登场了,解决3个问题: ...
- 2024年常用的Python可视化框架及开源项目
以下是 2024 年一些较为流行的 Python 可视化框架及开源项目: Matplotlib 框架声明:是 Python 中最基础.最广泛使用的可视化库之一,用于创建各种静态.动态和交互式图表. 官 ...
- Sqoop简介安装及使用
Sqoop简介 sqoop 是 apache 旗下一款"Hadoop 和关系数据库服务器之间传送数据"的工具. 核心的功能有两个: 导入.迁入 导出.迁出 导入数据:MySQL,O ...
- 基于全息感知的智慧高速IT设施监控运维方案
作为智能交通的重要细分领域,建设智慧高速是实施交通强国战略的重要基础.在信息化时代,交通行业已经依托信息化建设取得了显著的成果,其中以收费网络.办公网络.监控网络和通讯网络为基础的网络架构已经形成,并 ...