golang操作kafka

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

go get github.com/Shopify/[email protected]

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
		}
	}
}

你可能感兴趣的:(kafka,go,golang,kafka)