golang操作kafka

1. 下载安装kafka第三方工具包 我这使用的是1.27.2版本

go get github.com/Shopify/sarama@v1.27.2

2. 同步 生产者发送消息

func getSyncProducer() (sarama.SyncProducer, error) {
	config := sarama.NewConfig()
	// 返回指定要填充的通道。如果它们设置为true,则必须从相应的通道中读取,以防止死锁。
	// 但是,如果此配置用于创建“SyncProducer”,则两者都必须设置为true,并且您不能从通道中读取,因为生产者在内部执行此操作。
	config.Producer.Return.Successes = true
	config.Producer.Return.Errors = true
	producer, err := sarama.NewSyncProducer([]string{"localhost:9092"}, config)

	return producer, err
}

func SyncProducer() {
	producer, err := getSyncProducer()
	if err != nil {
		log.Fatalln(err)
	}
	defer func() {
		if err := producer.Close(); err != nil {
			log.Fatalln(err)
		}
	}()

	msg := &sarama.ProducerMessage{Topic: "test_topic", Value: sarama.StringEncoder("hello 123")}
	partition, offset, err := producer.SendMessage(msg)
	if err != nil {
		log.Printf("FAILED to send message: %s\n", err)
	} else {
		log.Printf("> message sent to partition %d at offset %d\n", partition, offset)
	}
}

3. 异步 生产者发送消息 适用于并发量大场景

func getAsyncProducer() (sarama.AsyncProducer, error) {
	config := sarama.NewConfig()
	// 返回指定要填充的通道。如果它们设置为true,则必须从相应的通道中读取,以防止死锁。
	// 但是,如果此配置用于创建“SyncProducer”,则两者都必须设置为true,并且您不能从通道中读取,因为生产者在内部执行此操作。
	config.Producer.Return.Successes = true
	config.Producer.Return.Errors = true
	// 控制消息被批量处理并发送到代理的频率。默认情况下,消息会尽可能快地发送
	config.Producer.Flush.Frequency = 500 * time.Millisecond //Flush batches every 500ms
	// 对消息使用的压缩类型(默认为无压缩)
	//config.Producer.Compression = sarama.CompressionSnappy   //Compress messages
	producer, err := sarama.NewAsyncProducer([]string{"localhost:9092"}, config)

	// 生产环境下应这样操作
	//if err != nil {
	//	return nil, err
	//}
	//go func() {
	//	for {
	//		select {
	//		// 此处可以做一些事情
	//		case <-producer.Successes():
	//		// 此处可以做一些事情
	//		case fail := <-producer.Errors():
	//			if fail != nil {
	//				fmt.Println(fail.Error())
	//			}
	//		}
	//	}
	//}()

	return producer, err
}

// 适用于并发量大场景
func AsyncProducer() {
	producer, err := getAsyncProducer()
	if err != nil {
		panic(err)
	}
	defer func() {
		if err := producer.Close(); err != nil {
			log.Fatalln(err)
		}
	}()

	// 发送消息
	message := &sarama.ProducerMessage{Topic: "test_topic", Value: sarama.StringEncoder("hello 6666")}
	producer.Input() <- message

	// 此处为了测试 打印结果 开始
	var wg sync.WaitGroup

	wg.Add(1)
	go func() {
		defer wg.Done()

		// 注意 如果 Return.Successes 和 Return.Errors 设置为true,则必须从相应的通道中读取,以防止死锁。
		select {
		case d := <-producer.Successes():
			fmt.Println(d)
			break
		case err := <-producer.Errors():
			fmt.Println(err)
			break
		}
	}()
	// 此处为了测试 打印结果 结束

	wg.Wait()
}

4. 消费消息

// 消费者
func Consumer() {
	consumer, err := sarama.NewConsumer([]string{"192.168.223.134:9092"}, nil)
	if err != nil {
		panic(err)
	}

	defer func() {
		if err := consumer.Close(); err != nil {
			log.Fatalln(err)
		}
	}()

	partitionConsumer, err := consumer.ConsumePartition("test_topic", 0, sarama.OffsetNewest)
	if err != nil {
		panic(err)
	}

	defer func() {
		if err := partitionConsumer.Close(); err != nil {
			log.Fatalln(err)
		}
	}()

	// Trap SIGINT to trigger a shutdown.
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, os.Interrupt)

	consumed := 0
ConsumerLoop:
	for {
		select {
		case msg := <-partitionConsumer.Messages():
			log.Printf("Consumed message offset %d\n", msg.Offset)
			fmt.Println(string(msg.Value))
			consumed++
		case <-signals:
			break ConsumerLoop
		}
	}
}

<think>嗯,用户想了解如何在Go语言中调用Kafka。首先,我需要回忆一下Golang中常用的Kafka客户端库。我记得有几个比较流行的,比如Sarama和confluent-kafka-go。Sarama是纯Go实现的,而confluent-kafka-go是基于librdkafka的C库,可能性能更好但需要依赖C库。用户可能对这两个库的区别不太清楚,所以可能需要简单介绍一下两者的优缺点,方便他们选择。 接下来,用户可能需要一个基本的示例,展示如何生产消息和消费消息。Sarama的例子应该包括创建生产者、发送消息、处理成功或错误的部分。消费者部分可能需要展示如何连接到集群、订阅主题、循环接收消息。同时,需要注意消费者组的设置,因为在实际应用中通常会用到消费者组来实现负载均衡。 另外,用户可能关心配置参数,比如Broker地址、Topic名称、如何设置ACK机制(比如是否需要等待所有副本确认)。生产环境中的一些最佳实践,比如错误处理、重试机制、连接池的管理,可能也需要提及。比如,Sarama的异步生产者可能会有不同的配置,需要根据吞吐量和可靠性需求调整。 还有,是否需要提到Kafka的版本兼容性?不同的Kafka版本可能需要不同的客户端配置,或者某些功能是否可用。比如,在使用Sarama的时候,需要确保客户端版本和服务器版本兼容,否则可能会遇到协议错误。 然后,用户可能对如何管理消费者位移有疑问,比如手动提交还是自动提交。在示例中,可能默认是自动提交,但实际应用中可能需要手动管理以确保消息不被丢失。比如在处理完消息后再提交offset,避免消息处理失败但offset已经提交的情况。 另外,可能需要注意上下文管理和优雅关闭,比如在消费者循环中监听退出信号,确保资源正确释放。还有错误处理,比如网络中断后的重连机制,或者如何处理消费过程中的错误。 最后,是否需要推荐一些更高级的库或框架,比如Shopify的sarama库是否有其他封装好的工具,或者是否有基于Sarama的更高层次的抽象,以便简化开发。例如,可以使用一些框架来简化消费者和生产者的创建和管理。 总结下来,回答的结构应该是先介绍库的选择,然后分别给出生产者和消费者的代码示例,说明关键步骤,接着讨论一些注意事项和最佳实践,比如配置、错误处理、位移管理等。可能还需要提到相关的文档和资源链接,方便用户进一步学习。</think>在 Go 语言中调用 Kafka 通常使用第三方库实现,常用的库是 **Sarama**(纯 Go 实现)和 **confluent-kafka-go**(基于 C 库的封装)。以下是使用 Sarama 的基本示例和关键步骤: --- ### 一、安装 Sarama ```bash go get github.com/IBM/sarama ``` --- ### 二、生产者示例(发送消息) ```go package main import ( "fmt" "log" "github.com/IBM/sarama" ) func main() { // 配置生产者 config := sarama.NewConfig() config.Producer.Return.Successes = true // 确保消息发送成功 // 创建生产者 producer, err := sarama.NewSyncProducer([]string{"localhost:9092"}, config) if err != nil { log.Fatalf("Failed to create producer: %v", err) } defer producer.Close() // 构造消息 msg := &sarama.ProducerMessage{ Topic: "test-topic", Key: sarama.StringEncoder("key1"), Value: sarama.StringEncoder("Hello Kafka"), } // 发送消息 partition, offset, err := producer.SendMessage(msg) if err != nil { log.Fatalf("Failed to send message: %v", err) } fmt.Printf("Sent message to partition %d, offset %d\n", partition, offset) } ``` --- ### 三、消费者示例(消费消息) ```go package main import ( "fmt" "log" "os" "os/signal" "github.com/IBM/sarama" ) func main() { // 配置消费者 config := sarama.NewConfig() config.Consumer.Return.Errors = true // 创建消费者 consumer, err := sarama.NewConsumer([]string{"localhost:9092"}, config) if err != nil { log.Fatalf("Failed to create consumer: %v", err) } defer consumer.Close() // 订阅主题 partitionConsumer, err := consumer.ConsumePartition("test-topic", 0, sarama.OffsetNewest) if err != nil { log.Fatalf("Failed to consume partition: %v", err) } defer partitionConsumer.Close() // 监听信号以优雅退出 signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt) // 循环消费消息 ConsumerLoop: for { select { case msg := <-partitionConsumer.Messages(): fmt.Printf("Received message: Key=%s, Value=%s\n", string(msg.Key), string(msg.Value)) case err := <-partitionConsumer.Errors(): log.Printf("Consumer error: %v\n", err) case <-signals: break ConsumerLoop } } } ``` --- ### 四、关键注意事项 1. **配置参数** - `Return.Successes`(生产者):需设置为 `true` 以确保消息发送成功。 - `Consumer.Offsets.Initial`(消费者):可设为 `sarama.OffsetOldest`(从头消费)或 `sarama.OffsetNewest`(从最新消息开始)。 2. **消费者组** 如需使用消费者组实现负载均衡,可使用 `sarama.NewConsumerGroup`,并实现 `sarama.ConsumerGroupHandler` 接口。 3. **异步生产者** 对高性能场景,使用 `sarama.NewAsyncProducer` 并监听 `Successes` 和 `Errors` 通道。 4. **错误处理** - 生产者需处理 `Errors` 通道。 - 消费者需处理分区再平衡(如服务重启时)。 5. **依赖问题** - 若选择 `confluent-kafka-go`,需安装 `librdkafka`(C 库),适合高吞吐场景。 --- ### 五、推荐实践 - **连接池管理**:复用生产者和消费者实例,避免频繁创建/销毁。 - **消息序列化**:使用 JSON、Protobuf 等格式序列化消息体。 - **监控指标**:集成 Prometheus 等工具监控 Kafka 客户端性能。 --- ### 六、官方资源 - [Sarama GitHub](https://github.com/IBM/sarama) - [confluent-kafka-go 文档](https://github.com/confluentinc/confluent-kafka-go) 通过上述步骤,你可以快速实现 Go 与 Kafka 的集成。根据业务需求选择合适的库和配置参数即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值