通过Java JMX获取Apache Kafka broker指标出现连接拒绝问题求解
问题修正方案
1. MBean相关疑问解答
无需自行开发Kafka相关MBean,Kafka服务端启动时已自动将所有内置监控指标对应的MBean注册到MBeanServer,直接采集服务端已暴露的MBean即可。
2. 配置错误修正
你当前的核心错误是kafka-server-start.sh中的配置顺序错误:export JMX_PORT=9999写在了exec命令之后,exec执行时会直接替换当前shell进程为Kafka进程,后续的所有语句都不会执行,因此脚本内配置的JMX_PORT并未生效。
正确的kafka-server-start.sh修改如下:
export JMX_PORT=9999 exec $base_dir/kafka-run-class.sh $EXTRA_ARGS kafka.Kafka "$@"
如果你启动服务时已经手动指定了JMX_PORT=9999 ./bin/kafka-server-start.sh config/server.properties参数仍连接失败,可先排查两个点:
- 执行
lsof -i:9999确认9999端口是否被Kafka进程正常监听,是否存在端口占用 - 检查
kafka-run-class.sh中是否有其他位置覆盖了KAFKA_JMX_OPTS配置,导致JMX远程访问被关闭
3. 代码优化建议
当前采集逻辑本身没有问题,等JMX配置生效后即可正常连接,可简化属性获取逻辑:Kafka所有指标MBean的取值都存放在Value属性中,无需遍历所有属性:
package server.kafka.metrics; import javax.management.*; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class Server { public static void main(String[] args) throws Exception{ try{ System.out.println("Connection to JMX kafka..."); JMXServiceURL url=new JMXServiceURL("service:jmx:rmi:///jndi/rmi://127.0.0.1:9999/jmxrmi"); JMXConnector jmxc = JMXConnectorFactory.connect(url,null); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); ObjectName mbeanName = new ObjectName("kafka.server:type=ReplicaManager,name=UnderMinIsrPartitionCount"); // 直接获取Value属性即可 Object metricValue = mbsc.getAttribute(mbeanName, "Value"); System.out.println("UnderMinIsrPartitionCount: " + metricValue); jmxc.close(); }catch (Exception e){ e.printStackTrace(); System.exit(0); } } }
4. 其他排查注意事项
- 查看Kafka启动日志,确认是否存在JMX相关报错,比如端口绑定失败、权限不足等
- 如果Kafka部署在远程服务器,需要将
kafka-run-class.sh中的-Djava.rmi.server.hostname=localhost修改为Kafka服务器的实际公网/内网IP,否则远程连接会失败
5. MySQL写入建议
采集逻辑跑通后,可通过ScheduledExecutorService实现定时采集,使用JDBC/MyBatis等框架将指标名称、指标数值、采集时间戳三个核心字段写入MySQL即可。
内容的提问来源于stack exchange,提问作者Shunmusiva
相关产品推荐
相关产品推荐

