kafka-go配置使用及调优

安装 

go get github.com/segmentio/kafka-go

生产者

常用配置

writer = &kafka.Writer{
		Addr:         kafka.TCP(kafkaAddress), // 设置Kafka的TCP连接地址(配置)
		Topic:        topicName,               // 设置要写入的主题名称(配置)
		Balancer:     &kafka.LeastBytes{},     // 选择分区策略,这里使用最小字节策略(保持)
		BatchSize:    100,                     // 设置批次大小,以消息数量为单位(选填)
		BatchBytes:   1024 * 1024,             // 设置批次字节大小上限(选填)
		BatchTimeout: 1 * time.Second,         // 批次超时时间,触发批量发送的超时机制(选填)
		Async:        true,                    // 使用异步模式发送消息,提高吞吐量(保持)
		RequiredAcks: kafka.RequireOne,        // 设置应答级别,仅需一个副本确认,平衡可靠性和性能(保持,默认kafka.RequireNone)
		Compression:  kafka.Snappy,            // 使用Snappy压缩以减少网络传输量(选填)
	}

(选填)仅调优时适当调整,一般不需要管。(保持)保持默认即可,通常的配置。(配置)后面有完整示例。

测试连接是否成功

conn, err := kafka.Dial("tcp", kafkaAddress)
	if err != nil {
		fmt.Printf("连接Kafka broker失败: %v", err)
		return
	}
	defer conn.Close()

检查是否有对应topic

_, err = conn.ReadPartitions(topicName)
	if err != nil {
		fmt.Printf("找不到topic %s: %v", topicName, err)
		writer.Close()
		return
	}

写入消息

err := writer.WriteMessages(context.Background(),
			kafka.Message{
				Value: []byte("Hello Kafka"),
			},
		)
		if err != nil {
			log.Printf("写入消息失败: %v", err)
			c.JSON(500, gin.H{"error": "写入消息失败"})
			return
		}

生产者完整代码

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/segmentio/kafka-go"
)

// Kafka 配置
const (
	kafkaAddress = "127.0.0.1:9092"
	topicName    = "test"
)

// 全局 Kafka Writer 实例
var writer *kafka.Writer

func initKafkaWriter() {
	writer = &kafka.Writer{
		Addr:         kafka.TCP(kafkaAddress), // 设置Kafka的TCP连接地址(配置)
		Topic:        topicName,               // 设置要写入的主题名称(配置)
		Balancer:     &kafka.LeastBytes{},     // 选择分区策略,这里使用最小字节策略(保持)
		BatchSize:    100,                     // 设置批次大小,以消息数量为单位(选填)
		BatchBytes:   1024 * 1024,             // 设置批次字节大小上限(选填)
		BatchTimeout: 1 * time.Second,         // 批次超时时间,触发批量发送的超时机制(选填)
		Async:        true,                    // 使用异步模式发送消息,提高吞吐量(保持)
		RequiredAcks: kafka.RequireOne,        // 设置应答级别,仅需一个副本确认,平衡可靠性和性能(保持,默认kafka.RequireNone)
		Compression:  kafka.Snappy,            // 使用Snappy压缩以减少网络传输量(选填)
	}

	// 测试连接 Kafka
	conn, err := kafka.Dial("tcp", kafkaAddress)
	if err != nil {
		fmt.Printf("连接Kafka broker失败: %v", err)
		return
	}
	defer conn.Close()

	// 确保 topic 存在
	_, err = conn.ReadPartitions(topicName)
	if err != nil {
		fmt.Printf("找不到topic %s: %v", topicName, err)
		writer.Close()
		return
	}
	fmt.Println("连接Kafka broker成功")
}

func main() {
	initKafkaWriter()
	r := gin.Default()
	r.GET("/write", func(c *gin.Context) {
		// 写入消息
		err := writer.WriteMessages(context.Background(),
			kafka.Message{
				Value: []byte("Hello Kafka"),
			},
		)
		if err != nil {
			log.Printf("写入消息失败: %v", err)
			c.JSON(500, gin.H{"error": "写入消息失败"})
			return
		}

		log.Println("写入消息成功")
		c.JSON(200, gin.H{"message": "写入消息成功"})
	})

	// 启动服务器
	r.Run()

}

消费者

常用配置

r = kafka.NewReader(kafka.ReaderConfig{
		Brokers:        []string{kafkaAddress}, // 设置Kafka代理地址列表(配置)
		Topic:          topicName,              // 指定要读取的主题(配置)
		GroupID:        consumergroup,          // 设置消费者组ID,支持消费组管理(配置)
		MinBytes:       1,                      // 设置单次读取的最小字节数(选填)
		MaxBytes:       10e6,                   // 设置单次读取的最大字节数为10MB(保持)
		MaxWait:        10 * time.Second,       // 获取批处理时等待新数据的最大时间(选填)
		StartOffset:    kafka.LastOffset,       // 指定读取的起始偏移量,从最新的消息开始(保持,默认kafka.FirstOffset)
		CommitInterval: 0,                      // 自动提交偏移量的时间间隔,为0时为同步提交(保持,每秒time.Second)
	})

读取消息

for {
		m, err := r.ReadMessage(context.Background())
		if err != nil {
			log.Printf("读取消息时出错: %v", err)
			break
		}

		fmt.Printf("主题/分区/偏移量 %v/%v/%v: %s = %s\n", m.Topic, m.Partition, m.Offset, string(m.Key), string(m.Value))
	}

	if err := r.Close(); err != nil {
		log.Fatal("failed to close reader:", err)
	}

消费者完整代码

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/segmentio/kafka-go"
)

// Kafka 配置
const (
	kafkaAddress  = "127.0.0.1:9092"
	topicName     = "test"
	consumergroup = "consumer-group-id"
)

var r *kafka.Reader

func initKafkaReader() {
	r = kafka.NewReader(kafka.ReaderConfig{
		Brokers:        []string{kafkaAddress}, // 设置Kafka代理地址列表(配置)
		Topic:          topicName,              // 指定要读取的主题(配置)
		GroupID:        consumergroup,          // 设置消费者组ID,支持消费组管理(配置)
		MinBytes:       1,                      // 设置单次读取的最小字节数(选填)
		MaxBytes:       10e6,                   // 设置单次读取的最大字节数为10MB(保持)
		MaxWait:        10 * time.Second,       // 获取批处理时等待新数据的最大时间(选填)
		StartOffset:    kafka.LastOffset,       // 指定读取的起始偏移量,从最新的消息开始(保持,默认kafka.FirstOffset)
		CommitInterval: 0,                      // 自动提交偏移量的时间间隔,为0时为同步提交(保持,每秒time.Second)
	})

	// 测试连接 Kafka
	conn, err := kafka.Dial("tcp", kafkaAddress)
	if err != nil {
		fmt.Printf("连接Kafka broker失败: %v", err)
		return
	}
	defer conn.Close()

	// 确保 topic 存在
	_, err = conn.ReadPartitions(topicName)
	if err != nil {
		fmt.Printf("找不到topic %s: %v", topicName, err)
		r.Close()
		return
	}
	fmt.Println("连接Kafka broker成功")

}

func main() {
	initKafkaReader()
	fmt.Println("开始消费消息...")
	for {
		m, err := r.ReadMessage(context.Background())
		if err != nil {
			log.Printf("读取消息时出错: %v", err)
			break
		}

		fmt.Printf("主题/分区/偏移量 %v/%v/%v: %s = %s\n", m.Topic, m.Partition, m.Offset, string(m.Key), string(m.Value))
	}

	if err := r.Close(); err != nil {
		log.Fatal("failed to close reader:", err)
	}
}

gitee示例

https://gitee.com/alsark/kafka-go-demo.githttps://gitee.com/alsark/kafka-go-demo.githttps://gitee.com/alsark/kafka-go-demo.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值