某项目hiveserver2 jmx采集异常告警,几分钟后同主机其他组件 jmx采集异常也发出告警,hiveserver2恢复后,其他组件采集也恢复正常。
2、排查
查看日志,hiveserver2异常时在频繁full gc,其他组件均正常。
写了一个持续 full gc的demo,扔到测试环境测试,可以复现问题。jstack jmx-exporter进程发现,5个线程都卡在socket读。
查看TCPChannel.java,var5 是rmi客户端的socket 输入流。 demo现在持续full gc,无法提供数据,所以var5.readByte()一直block。
代码中提供了rmi客户端 socket几个属性的默认值,其中sun.rmi.transport.tcp.responseTimeout默认值0,即无超时限制。
private static final long idleTimeout = (Long)AccessController.doPrivileged(new GetLongAction("sun.rmi.transport.connectionTimeout", 15000L));
private static final int handshakeTimeout = (Integer)AccessController.doPrivileged(new GetIntegerAction("sun.rmi.transport.tcp.handshakeTimeout", 60000));
private static final int responseTimeout = (Integer)AccessController.doPrivileged(new GetIntegerAction("sun.rmi.transport.tcp.responseTimeout", 0));
private static final ScheduledExecutorService scheduler = ((RuntimeUtil)AccessController.doPrivileged(new GetInstanceAction())).getScheduler();
修改jmx exporter启动命令,添加配置 -Dsun.rmi.transport.tcp.responseTimeout=10000,即10s。
重新测试,demo 持续gc异常不影响其他组件的jmx采集。
3、解决方法
修改jmx-exporter启动命令,添加RMI 超时时间设置
java -Xms2g -Xmx2g -Dsun.rmi.transport.tcp.responseTimeout=10000 -cp /usr/local/prometheus-jmx-exporter/jmx_prometheus_httpserver.jar io.prometheus.jmx.WebServer 0.0.0.0:1999 /etc/prometheus/conf/jmx-exporter