Go 用 sarama 接入 Kafka:生产者、消费者组与分区实战
test12026-10-173 次阅读
场景
Kafka 适合做削峰填谷和事件驱动。Go 侧最常用的客户端是 IBM 维护的 sarama。本文用订单事件为例,演示如何发消息、如何以消费者组方式消费并按分区并行处理。
生产者:发一条订单事件
package main
import (
"log"
"github.com/IBM/sarama"
)
func main() {
brokers := []string{"localhost:9092"}
cfg := sarama.NewConfig()
cfg.Producer.Return.Successes = true
cfg.Producer.Partitioner = sarama.NewRandomPartitioner
producer, err := sarama.NewSyncProducer(brokers, cfg)
if err != nil {
log.Fatal(err)
}
defer producer.Close()
msg := &sarama.ProducerMessage{
Topic: "order-events",
Key: sarama.StringEncoder("order-1001"),
Value: sarama.StringEncoder(`{"id":"order-1001","amount":99}`),
}
partition, offset, err := producer.SendMessage(msg)
if err != nil {
log.Fatal(err)
}
log.Printf("sent to partition %d offset %d", partition, offset)
}
消费者组:批量处理事件
type handler struct{}
func (h *handler) Setup(sarama.ConsumerGroupSession) error { return nil }
func (h *handler) Cleanup(sarama.ConsumerGroupSession) error { return nil }
func (h *handler) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
for msg := range claim.Messages() {
log.Printf("topic=%s partition=%d value=%s", msg.Topic, msg.Partition, string(msg.Value))
sess.MarkMessage(msg, "")
}
return nil
}
func consume() {
cfg := sarama.NewConfig()
cfg.Consumer.Offsets.Initial = sarama.OffsetOldest
group, _ := sarama.NewConsumerGroup([]string{"localhost:9092"}, "order-group", cfg)
for {
_ = group.Consume(context.Background(), []string{"order-events"}, &handler{})
}
}
分区与消费者组的工程要点
- 同一个 group 内,一个分区只会被一个消费者实例消费,实例数不要超过分区数,否则有实例空转。
- 用稳定业务键(如 orderId)做 Key,保证同一订单的事件落到同一分区,顺序得以保留。
- MarkMessage 才提交位移,处理失败先不提交,重启可从上次位置重放。
- 生产环境务必设置 RequiredAcks 和重试,避免消息静默丢失。
T
test1
文章作者
场景 Kafka 适合做削峰填谷和事件驱动。Go 侧最常用的客户端是 IBM 维护的 sarama。本文用订单事件为例...
- 分类
- 技术
- 发布时间
- 2026-10-17
- 字数
- 约 1712 字
- 阅读
- 3 次
