Kafka測試初探【Go】

上週分享了Kafka性能測試初探的Java版本,有讀者留言說太簡單,內容比較水。這裏澄清一下,是我學得比較水。文章定位就是一篇使用Java語言的Kafka Client客戶端進行簡單操作演示,然後模擬一下簡單場景的性能測試。其中深入學習Kafka的可以隨處搜到很權威實用的資料,有深入學習需求的可以自行尋找。

好久沒有寫Go了,這才突然覺察到,又重新複習了一波Go語言的基礎語法。順帶着之前留下的好習慣,每個學習的框架和工具都用Java和Go寫一遍。這次也分享一下Go語言的Kafka基礎入門,以及生產者的簡單測試場景。

我用的是shopify出的sarama,依賴如下github.com/Shopify/sarama v1.38.1。在搜資料的過程中,還發現有使用其他客戶端的,選擇挺多。

Kafka配置

Sarama框架中的生產者和消費者的配置類是一個,不太清楚這麼設計的意圖,兩個配置重合度並不高,在Sarama中也是分開配置,但使用了同一個配置類。

生產者配置:

	config := sarama.NewConfig()
	config.Producer.Return.Successes = true
	config.Producer.Return.Errors = true
	config.Producer.RequiredAcks = sarama.NoResponse
	config.Producer.Compression = sarama.CompressionLZ4
	config.Producer.Timeout = time.Duration(50) * time.Millisecond
	config.Producer.Retry.Max = 3

消費者配置:

	config := sarama.NewConfig()
	config.Consumer.Offsets.AutoCommit.Enable = true
	config.Consumer.Offsets.AutoCommit.Interval = 1 * time.Second
	config.Consumer.Offsets.Initial = sarama.OffsetOldest
	config.Consumer.Offsets.Retry.Max = 3

這裏只選擇部分參數,詳細的配置項和註釋都可以在源碼中找到,Sarama的一個好處就是註釋非常全,甚至不用看官方API文檔。

生產者

下面是生產者的代碼,相比較Java來說,我這裏增加了header的實踐,其實Java也是支持的,只是當時學的時候漏掉了這個知識點。

producer, err := sarama.NewSyncProducer([]string{"localhost:9092"}, config)
	if err != nil {
		log.Fatal(err)
		return
	}
	defer func() {
		// 關閉生產者
		if err = producer.Close(); err != nil {
			log.Fatal(err)
			return
		}
	}()
	// 定義需要發送的消息
	headers := []sarama.RecordHeader{sarama.RecordHeader{
		Key:   []byte("funtest"),
		Value: []byte("have fun ~"),
	}}

	msg := &sarama.ProducerMessage{
		Topic:   "topic_test",
		Key:     sarama.StringEncoder("test"),
		Value:   sarama.StringEncoder("ddddddddddddddddd"),
		Headers: headers,
	}
	// 發送消息,並獲取該消息的分片、偏移量
	for i := 0; i < 100; i++ {
		ftool.Sleep(1000)
		partition, offset, err := producer.SendMessage(msg)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("partition:%d offset:%d\n", partition, offset)
	}

這裏官方給的實踐代碼中感覺ProducerMessage類似於Java的org.apache.kafka.clients.producer.ProducerRecord#ProducerRecord,也是可以指定partitionid和時間戳,以及單獨設置retries次數的。還有一個比較重要的類AsyncProducer,暫時不探索了。

消費者

消費者使用上Go和Java差異比較大,Sarama用了channel的概念,可以一直不停止從服務端獲取消息對象,不像Java可以指定一次接受的消息數量,單次最大等待時間等。盲猜這裏channel的性能太好了吧,不需要複雜設計也能滿足需求。

	consumer, err := sarama.NewConsumer([]string{"localhost:9092"}, config)
	if err != nil {
		fmt.Printf("fail to start consumer, err:%v\n", err)
		return
	}
	topic := "topic_test"
	partitionList, err := consumer.Partitions(topic) // 根據topic取到所有的分區
	if err != nil {
		fmt.Printf("fail to get list of partition:err%v\n", err)
		return
	}
	fmt.Println(partitionList)
	defer consumer.Close()
	for partition := range partitionList { // 遍歷所有的分區
		// 針對每個分區創建一個對應的分區消費者
		log.Println(partition)
		pc, err := consumer.ConsumePartition(topic, int32(partition), sarama.OffsetOldest)
		if err != nil {
			fmt.Printf("failed to start consumer for partition %d,err:%v\n", partition, err)
		}
		for msg := range pc.Messages() {
			log.Println(string(msg.Value))
			//log.Println(string(msg.Headers[0].Value))
		}
		for {
			msg := <-pc.Messages()
			log.Println(string(msg.Value))
		}
	}

後來我寫了兩種接受方式,其實都是阻塞的,如果是性能測試的時候可以使用Go中的go關鍵字起routine來執行。

性能測試

我這之展示性能測試簡單的例子,即生產者不停地往Kafka發消息的Demo,複用了上文中的生產者代碼,下面只展示執行部分。

execute.ExecuteRoutineTimes(func() {
	_, _, _ := producer.SendMessage(msg)
}, 100, 10)

執行方法ExecuteRoutineTimes是我寫的一個基於線程模型的壓測執行方法,內容如下:


// ExecuteRoutineTimes
// @Description: FunTester性能測試執行框架
// @param fun 待執行方法
// @param times 次數
// @param routine 線程數
func ExecuteRoutineTimes(fun func(), times, routine int) {
	c := make(chan int) //確認所有線程都結束
	key := false        //用於控制所有線程一起結束
	start := ftool.Milli()
	for i := 0; i < routine; i++ {
		go func() {
			sum := 0
			for i := 0; i < times; i++ {
				if key {
					break
				}
				fun()
				sum++
			}
			key = true
			c <- sum
		}()
	}
	total := 0
	for i := 0; i < routine; i++ {
		num := <-c
		total += num
	}
	end := ftool.Milli()
	diff := end - start
	//total := thread * times
	log.Printf("總耗時: %f", float64(diff)/1000)

	log.Printf("請求總數: %d", total)
	log.Printf("QPS: %f", float64(total)/float64(diff)*1000.0)
}

總結起來,相比Java,Go語言相對簡單一些。如果習慣了Go語言的習慣,對於做測試來說上手要比Java快一些。再買個坑,改天測試一下兩者之間的性能差異。理論上Go要比Java好一些。

Sarama是一個用於Apache Kafka的Go語言庫。Kafka是一個分佈式流處理平臺,它可以處理大規模的數據流,並將其發佈到主題中,供其他應用程序使用。Sarama庫允許Go應用程序與Kafka集羣進行通信。它支持多個版本的Kafka協議,並提供了生產者和消費者API,以便應用程序可以輕鬆地將消息發佈到Kafka主題或從中讀取消息。Sarama還提供了一些有用的工具,如分區選擇器和負載平衡器,以幫助開發人員更好地管理Kafka消費者。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章