







1 2 | // Subscribe to the given list of topics to get dynamically assigned partitions.void subscribe(Collection<String> topics, ConsumerRebalanceListener listener) |
1 2 | // Manually assign a list of partitions to this consumer.void assign(Collection<TopicPartition> partitions) |

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | package main import ( "context" "sync" "time" "github.com/Shopify/sarama") type ConsumerHandler func(partition int32, partitionConsumer sarama.PartitionConsumer, message *sarama.ConsumerMessage) func NewConsumer(addrs []string, config *sarama.Config) (sarama.Consumer, error) { if config == nil { config = sarama.NewConfig() // Aliyun kafka version 2.2.0 config.Version = sarama.V2_0_0_0 } return sarama.NewConsumer(addrs, config)} // Consume start consume, will block until exit, call in `goroutine`// note: `handle` called in `goroutine`func Consume(ctx context.Context, consumer sarama.Consumer, topic string, handle ConsumerHandler) error { defer consumer.Close() // 获取所有分区 partitions, err := consumer.Partitions(topic) if err != nil { return err } // 消费所有分区 waitGroup := sync.WaitGroup{} for k, part := range partitions { p, err := consumer.ConsumePartition(topic, part, sarama.OffsetNewest) if err != nil { return err } waitGroup.Add(1) go func(partition int32, partitionConsumer sarama.PartitionConsumer) { defer waitGroup.Done() defer partitionConsumer.AsyncClose() for { select { case <-ctx.Done(): return case m := <-partitionConsumer.Messages(): handle(partition, partitionConsumer, m) default: time.Sleep(time.Millisecond) } } }(int32(k), p) } waitGroup.Wait() return nil} |
main.go中使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | func main() { // create and start consumer consumer, err := NewConsumer(kafkaAddr, nil) if err != nil { panic(err) } for { log.Println("consumer is running...") // will block err := Consume(context.Background(), consumer, topic, func(partition int32, partitionConsumer sarama.PartitionConsumer, message *sarama.ConsumerMessage) { log.Println("consumer new mq, paritition=", partition, ",topic:", message.Topic, ",offset:", message.Offset) }) if err != nil { log.Println(err) } else { log.Println("consume exit") } time.Sleep(time.Second * 3) }} |
producer代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | func startProducer(addrs []string, topic string) { config := sarama.NewConfig() config.Producer.RequiredAcks = sarama.WaitForAll config.Producer.Partitioner = sarama.NewRandomPartitioner config.Producer.Return.Successes = true producer, err := sarama.NewSyncProducer(addrs, config) if err != nil { panic(err) } for i := 0; i < 1000; i++ { p, offset, err := producer.SendMessage(&sarama.ProducerMessage{ Key: sarama.StringEncoder(strconv.Itoa(i)), Value: sarama.StringEncoder("hello" + strconv.Itoa(i)), Topic: topic, }) if err != nil { log.Println(err) } else { log.Println("produce success, partition:", p, ",offset:", offset) } time.Sleep(time.Second) } log.Println("exit producer.")} |
效果如下:



1 | map[int64]tcp.Conn |

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70000523/viewspace-3138198/ ,如需转载,请注明出处,否则将追究法律责任。