介绍
在使用JMX(Java Management Extensions)进行监控时,可能会遇到"SEVERE: JMX scrape failed: java.rmi.ConnectException: Connection refused"的错误。这种错误通常意味着在尝试通过RMI(Remote Method Invocation)协议进行连接时失败。本博客将介绍一些排查和解决此问题的步骤。
比如在启动jmx_exporter时发现错误
SEVERE: JMX scrape failed: java.rmi.ConnectException: Connection refused to host: x.x.x.x; nested exception is:
java.net.ConnectException: Connection refused (Connection refused)
at java.rmi/sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:623)
at java.rmi/sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:209)
at java.rmi/sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:196)
at java.rmi/sun.rmi.server.UnicastRef.invoke(UnicastRef.java:132)
at java.management.rmi/javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)
at java.management.rmi/javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2105)
at java.management.rmi/javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:321)
at java.management/javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:270)
at io.prometheus.jmx.JmxScraper.doScrape(JmxScraper.java:156)
at io.prometheus.jmx.JmxCollector.collect(JmxCollector.java:781)
at io.prometheus.metrics.model.registry.PrometheusRegistry.scrape(PrometheusRegistry.java:84)
at io.prometheus.metrics.model.registry.PrometheusRegistry.scrape(PrometheusRegistry.java:66)
at io.prometheus.metrics.exporter.opentelemetry.PrometheusMetricProducer.collectAllMetrics(PrometheusMetricProducer.java:45)
at io.prometheus.metrics.shaded.io_opentelemetry_2_10_0_alpha.sdk.metrics.export.PeriodicMetricReader$Scheduled.doRun(PeriodicMetricReader.java:161)
at io.prometheus.metrics.shaded.io_opentelemetry_2_10_0_alpha.sdk.metrics.export.PeriodicMetricReader$Scheduled.run(PeriodicMetricReader.java:153)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:609)
at java.base/java.net.Socket.connect(Socket.java:558)
at java.base/java.net.Socket.<init>(Socket.java:454)
at java.base/java.net.Socket.<init>(Socket.java:231)
at java.rmi/sun.rmi.transport.tcp.TCPDirectSocketFactory.createSocket(TCPDirectSocketFactory.java:40)
at java.rmi/sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:617)
排查方向
-
检查JMX服务器配置
- 确保JMX服务正确配置,RMI连接端口开放。
- 确保JMX URL和端口正确无误。
-
RMI 配置
- 检查
java.rmi.server.hostname是否设置为有效的、可访问的IP地址。 - 如何设置:docs.confluent.io/platform/7.…
- 检查
-
日志检查
- 查看服务器和应用的日志文件以获取更多错误细节。
-
安全设置
- 如果启用了SSL/TLS,请确保证书配置无误并且JMX客户端支持相应协议。
解决问题步骤
-
分析Kafka日志
通过查看Kafka的日志,发现Kafka的hostname配置的IP地址与本机的实际IP地址不一致。这也与jmx_exporter所提供的信息一致,表明问题的根源在于hostname配置。可以优先关注kafkaServer.out 这个日志 -
验证其他问题方向
根据之前的排查方向进行详细检查,确认其他配置路径没有问题,这进一步证实问题可能出在hostname设置上。 -
检查本机的
hostname设置
调查发现本机的hostname被设置为一个公用域名。由于Kafka在未明确配置hostname时,会通过执行hostname -i来获取IP地址,因此导致获取错误的IP地址。 -
修改
hostname解决问题
将本机的hostname直接设置为正确的IP地址或域名,解决了问题。同时,需要检查是否在/etc/hosts或/etc/hostname配置文件中存在错误的设置,并进行相应的更正以防止类似问题的发生。
通过这些措施,成功解决了JMX监控连接失败的问题,确保Kafka的监控功能正常运作。