应直接使用 php-rdkafka 扩展,确保已安装 librdkafka 库和 php-rdkafka 扩展,正确配置 bootstrap.servers、group.id(消费者必需)、auto.offset.reset,并在生产者中强制调用 poll(),消费者需正确处理 RD_KAFKA_RESP_ERR__TIMED_OUT 等响应。

php-rdkafka 是当前 PHP 操作 Kafka 最稳定、性能最好、社区维护最活跃的扩展,不是 kafka-php(纯 PHP 实现,已多年未更新),也不是 pecl install kafka(该 PECL 扩展早已废弃,PHP 8+ 不兼容)。直接用 php-rdkafka,别绕弯。
确认系统已装 librdkafka 和 php-rdkafka 扩展
很多“连不上 broker”的问题,根源是扩展没真正生效,而不是代码写错。
- 先检查是否已安装 C 库:
ldconfig -p | grep rdka—— 若无输出,需手动装librdkafka1(Debian/Ubuntu)或librdkafka(CentOS/RHEL) - 再确认 PHP 扩展已启用:
php -m | grep rdkafka—— 若无输出,说明扩展未加载;不要只靠composer require ext-rdkafka,它不装扩展本体,只做提示 -
php --ri rdkafka必须能打印出版本号和配置项,否则后续所有代码都白跑
RdKafka\Conf 配置里必须设的三项
缺一不可,否则会卡在 metadata 请求或静默失败。
-
bootstrap.servers:必须用这个键名,不是metadata.broker.list(旧版兼容但不推荐);多个 broker 用逗号分隔,如"kafka1:9092,kafka2:9092" -
group.id:消费者必需,生产者可不设;但若消费者没设,newRdKafka\KafkaConsumer($conf)会抛RD_KAFKA_RESP_ERR__INVALID_ARG -
auto.offset.reset:消费者首次启动时从哪读,值必须是字符串"earliest"或"latest",不能是整数或常量RD_KAFKA_OFFSET_BEGINNING(那是 C 层用的)
producer->poll(0) 不是可选项,是强制动作
很多人发完消息就结束脚本,结果消息根本没发出去——因为 produce() 只是把消息塞进内部缓冲区,真正发送依赖 poll() 触发 librdkafka 的 I/O 循环。
- 单条消息后立刻调
$producer->poll(0),确保缓冲区 flush - 批量发送时,每发几条 poll 一次,或循环末尾加
while ($producer->getOutQLen() > 0) { $producer->poll(50); } - 漏掉 poll 的典型现象:
rdkafka日志里出现"%3|1747027682.123|FAIL|rdkafka#producer-1| [thrd:kafka1:9092/bootstrap]: kafka1:9092/bootstrap: Failed to resolve 'kafka1:9092': Name or service not known"—— 其实 DNS 是通的,只是 metadata 请求被卡在队列里没发出
消费者必须显式调用 consume() 并处理 RD_KAFKA_RESP_ERR__TIMED_OUT
$message = $consumer->consume(1000) 返回的 $message->err 常见值不是只有成功或失败,RD_KAFKA_RESP_ERR__TIMED_OUT 是正常流程,不代表出错。
立即学习“PHP免费学习笔记(深入)”;
- 不要一看到
$message->err !== RD_KAFKA_RESP_ERR_NO_ERROR就 exit 或 throw —— 它可能是超时,下一轮还会继续拉 - 真正要报警的是
RD_KAFKA_RESP_ERR__ALL_BROKERS_DOWN或RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART - 消费循环里别用
sleep(1),它会让 offset 提交延迟;应靠consume()的 timeout 参数控制节奏
librdkafka 的日志级别和错误回调。不打开 debug(如 $conf->set('debug', 'all'))或不设置 error_cb,很多连接拒绝、SASL 认证失败、SSL 握手超时的问题,都会静默吞掉,只剩一条 “failed to send message” 模糊提示。



















