Kafka 安裝配置、更多資料請參考其官網。
啟動 kafka server
在這之前需要啟動 zookeeper 做服務治理(單機)。
$ bin/zkServer.sh status conf/zoo_sample.cfg
如提示許可權限制加上 sudo
。
啟動 kafka server
$ bin/kafka-server-start.sh config/server.properties
啟動訊息佇列(本部分僅為測試 server)
建立 Topic
$ bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test$ bin/kafka-topics.sh --list --zookeeper localhost:2181 (test)
1. 啟動 Producer
$ bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
2. 啟動 Consumer
bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning
此時在 Producer 端發送訊息,在 Consumer 就會顯示,如所示。
(中 Consumer 多出了好幾個訊息是我之前測試發出的)
Action
本文使用 sarama 庫作為 kafka 的 go API。sarama 庫沒有給出很具體的文檔,可以參考其源碼。
Producer
package mainimport ( "fmt" "github.com/Shopify/sarama")func main() { config := sarama.NewConfig() config.Producer.RequiredAcks = sarama.WaitForAll config.Producer.Partitioner = sarama.NewRandomPartitioner config.Producer.Return.Successes = true addr := []string{"localhost:9092"} producer, err := sarama.NewSyncProducer(addr, config) if err != nil { panic(err) } defer producer.Close() msg := &sarama.ProducerMessage{ Topic: "hello", Partition: int32(-1), Key: sarama.StringEncoder("key"), } var value string for { _, err := fmt.Scanf("%s", &value) if err != nil { break } msg.Value = sarama.ByteEncoder(value) fmt.Println(value) partition, offset, err := producer.SendMessage(msg) if err != nil { fmt.Println("Send message Fail") } fmt.Printf("Partition = %d, offset=%d\n", partition, offset) }}
Consumer
package mainimport ( "fmt" "sync" "github.com/Shopify/sarama")var ( wg sync.WaitGroup)func main() { consumer, err := sarama.NewConsumer([]string{"localhost:9092"}, nil) if err != nil { panic(err) } partitionList, err := consumer.Partitions("hello") if err != nil { panic(err) } for partition := range partitionList { pc, err := consumer.ConsumePartition("hello", int32(partition), sarama.OffsetNewest) if err != nil { panic(err) } defer pc.AsyncClose() wg.Add(1) go func(sarama.PartitionConsumer) { defer wg.Done() for msg := range pc.Messages() { fmt.Printf("Partition:%d, Offset:%d, Key:%s, Value:%s\n", msg.Partition, msg.Offset, string(msg.Key), string(msg.Value)) } }(pc) } wg.Wait() consumer.Close()}
結果如下: