选sarama还是kafka-go需依场景而定:kafka-go简洁适合单分区验证,但默认不支持消费者组自动重平衡;sarama功能完整、适合严格语义生产环境,但需显式close()防泄露,且newsyncproducer可靠性取决于requiredacks配置。
go 操作 kafka 不难,但默认配置下极大概率丢消息、连不上、或消费卡死——关键在客户端选型、配置项取值和资源释放时机。
选 sarama 还是 kafka-go?看场景别硬套流行度
当前 GitHub star 最多的是 segmentio/kafka-go,但它默认不支持消费者组(ConsumerGroup)的自动重平衡逻辑,需手动处理 offset 提交和分区分配;而 Shopify/sarama 虽稍重,但 ConsumerGroup 实现完整,适合需要严格语义(如 at-least-once)的生产环境。
- 快速验证或单分区简单场景:用
kafka-go,API 更简洁,WriteMessages一行发消息,ReadMessage一行收 - 要对接已有 Kafka 集群、需精确控制重试/压缩/SSL/SASL、或必须用消费者组:选
sarama,尤其注意它不自动关闭底层连接,Close()必须显式调用 - 别在
init()里全局初始化生产者——它不是线程安全的,高并发下会 panic;应封装成带池或单例的结构体
sarama.NewSyncProducer 的坑:成功返回 ≠ 消息已落盘
NewSyncProducer 听起来“可靠”,但实际是否真能保证不丢,完全取决于 RequiredAcks 和 broker 配置。默认是 sarama.NoResponse,即发完就返回,broker 甚至没来得及写入页缓存。
-
sarama.WaitForAll+replication-factor = 1,它退化为等 leader 写完,仍可能丢 -
config.Producer.Return.Successes = true必须开,否则SendMessage成功后你根本不知道发到哪个partition和offset - 别忽略
producer.Close():不关会导致 goroutine 泄露和 TCP 连接堆积,Kafka broker 端日志会出现Connection reset类错误
kafka-go 消费者常见卡顿原因:offset 提交太勤或太懒
kafka-go 消费者 ReadMessage 默认是阻塞读,但卡住往往不是 Kafka 问题,而是应用层没管好 offset。
- 每条消息都立刻
CommitMessages:吞吐暴跌,网络 RTT 成瓶颈;且若提交后 crash,消息可能被重复消费 - 完全不提交、靠自动 commit(
AutoCommit: true):一旦 consumer 重启,会从上次自动保存位置开始,可能跳过未处理完的消息 - 推荐做法:批量处理 N 条后手动
CommitMessages,N 取 10–100,同时用context.WithTimeout包裹ReadMessage,防无限阻塞
本地调试连不上 localhost:9092?检查 broker 的 advertised.listeners
Kafka broker 默认只监听 localhost,但 Docker 或远程 client 会拿到 advertised.listeners 里的地址去连——如果它还是 localhost,就会连错。
- Docker 启动时务必显式设置:
advertised.listeners=PLAINTEXT://host.docker.internal:9092(Mac/Win)或对应宿主机 IP(Linux) - 本地 Go 程序若跑在容器外,Broker 的
advertised.listeners必须可被该机器直接路由和访问,否则会卡在 TCP connect timeout - 用
telnet host.docker.internal 9092或nc -vz host.docker.internal 9092先验证网络连通性,再查 Go 客户端报错
最常被忽略的是:sarama 的 ConsumerGroup 需要自己管理 session 超时与心跳,kafka-go 的 CommitInterval 在高吞吐下容易导致重复消费;而无论用哪个库,context 生命周期没和消息处理对齐,就会出现“看似消费了,实则没处理完就提交 offset”的静默丢失。











