Docker中运行的Kafka接收Github事件时出现Direct buffer内存溢出
Kafka Direct Buffer Memory 溢出问题解决方案
环境信息
- Kafka版本:7.2.1-ccs(Commit:80334008361592c187b36a27536f10f33fe93aa3)
- 部署方式:Docker容器
- Java版本:openjdk 11.0.15 LTS
- Docker Compose原配置:
version: '3.8' services: zookeeper: image: confluentinc/cp-zookeeper:7.2.1 environment: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 kafka: image: confluentinc/cp-kafka:7.2.1 ports: - <some ip @>:9092 environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_SOCKET_REQUEST_MAX_BYTES: 2147483647 KAFKA_Max_Direct_MemorySize KAFKA_HEAP_OPTS: -Xmx2G -Xms2G
问题现象
通过Github App Webhook推送事件到Kafka主题时,Kafka容器日志抛出java.lang.OutOfMemoryError: Direct buffer memory错误;用Postman发送测试消息功能正常,已移除该主题所有消费者。
错误堆栈:
ERROR Processor got uncaught exception. (kafka.network.Processor) java.lang.OutOfMemoryError: Direct buffer memory at java.base/java.nio.Bits.reserveMemory(Bits.java:175) at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:118) at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:317) at java.base/sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:242) at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:242) at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:223) at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:356) at org.apache.kafka.common.network.PlaintextTransportLayer.read(PlaintextTransportLayer.java:103) at org.apache.kafka.common.network.NetworkReceive.readFrom(NetworkReceive.java:118) at org.apache.kafka.common.network.KafkaChannel.receive(KafkaChannel.java:452) at org.apache.kafka.common.network.KafkaChannel.read(KafkaChannel.java:402) at org.apache.kafka.common.network.Selector.attemptRead(Selector.java:674) at org.apache.kafka.common.network.Selector.pollSelectionKeys(Selector.java:576) at org.apache.kafka.common.network.Selector.poll(Selector.java:481) at kafka.network.Processor.poll(SocketServer.scala:1144) at kafka.network.Processor.run(SocketServer.scala:1047) at java.base/java.lang.Thread.run(Thread.java:829)
已尝试无效操作
- 增加Docker资源并将
KAFKA_HEAP_OPTS调整至12G - 添加SSL安全协议相关配置
解决方案
1. 调整Direct Buffer内存限制
Direct Buffer内存与JVM堆内存相互独立,调大堆内存无法解决该问题。需通过JVM参数指定Direct Buffer的最大内存:
在Kafka服务的environment中添加:
KAFKA_JVM_PERFORMANCE_OPTS: "-XX:MaxDirectMemorySize=4G"
同时删除原配置中无效的KAFKA_Max_Direct_MemorySize项。
2. 匹配大请求相关参数
GitHub Webhook事件可能包含大负载(如代码推送的diff),需确保Kafka能处理大消息:
添加以下环境变量:
KAFKA_MESSAGE_MAX_BYTES: 2147483647
该值需与KAFKA_SOCKET_REQUEST_MAX_BYTES保持一致(当前已设为2G)。
3. 简化配置(可选)
开发阶段若无需SSL,可移除之前添加的SSL配置项,减少不必要的复杂度,优先解决内存问题。
4. 验证配置
- 重启Docker容器:
docker-compose down && docker-compose up -d - 进入容器验证JVM参数是否生效:
# 找到Kafka进程ID docker exec -it <kafka-container-name> jps # 查看MaxDirectMemorySize参数 docker exec -it <kafka-container-name> jcmd <kafka-pid> VM.flags | grep MaxDirectMemorySize - 重新触发GitHub Webhook事件,观察日志是否仍有内存溢出错误。
内容的提问来源于stack exchange,提问作者Fendri
相关产品推荐
相关产品推荐

