问题概述
客户端生产消息进入堵塞状态,核心原因是消息发送不出去,或者发送的速度小于生产的速度。
如果是发送不出去,有 time out 的提示,可以先使用命令行进行生产消费,查看集群基本性能。参考 命令行生产消费。 如果是发送的速度小于生产速度,有三种原因:
生产者的实例太少,即单个生产者的生产性能是有上限的,如果生产者的数量太少,流量太大,可能会导致发送堵塞。
流量太大,Topic 的分区数太少,导致写入并行度不够。
服务的质量有问题,例如网络质量下降,Broker 负载升高,客户端负载升高(例如客户端发生了 GC)会导致客户端发送到服务端的整体耗时上升,导致生产速率下降。从而导致客户端本地的 buffer 堆积,出现阻塞。
可能原因
1. 如果是专业版实例,可以在控制台查看高级监控,观察服务端的整体负载情况,如请求队列深度,生产消费的服务端耗时等。来确认服务端是否有性能问题。如果是标准版实例,可以 提交工单 查看这些指标。 2. 排查客户端负载,如本地机器的 CPU,内存情况(如果是 Java 客户端,重点关注 GC 情况)。
3. 如果是偶尔出现阻塞状况,需要排查本地网络是否有波动。特别是容器网络环境下,需要着重关注。
4. 分析生产者的数量是否过少,可以从单机的流量来分析。如果单机吞吐的流量较大,而生产者又是单线程发送,则需要关注。
解决方法
可以通过以下方法尝试解决问题:
1. 当生产消息的速度比 Sender 线程发送到 Broker 速度快,导致 buffer.memory 配置的内存用完时会阻塞生产者 send 操作,该参数设置最大的阻塞时间。如果需要更大的send buffer,可以通过调大 buffer.memory,buffer.memory 的默认值是 32MB。
max.block.ms=60000
buffer.memory=33554432
2. 如果 Topic 的流量较大,客户端发送的 Produce 实例较少,可以多起几个 Produce 实例来生产。例如:
KafkaProducer<byte[],byte[]> producer = new KafkaProducer<>(props);
3. 扩容集群的分区数。
本页内容是否解决了您的问题?