线上应用稳定运行,系统无告警,业务无投诉,都是研发伙伴们所期望的。
但最近生产环境出现一个问题,其中一个实例JVM内存爆满,频繁FullGC,从而导致出现MySQL获取不到连接,导致业务无法响应问题。
临时解决方案:将这个有问题的实例从注册中心摘除,以免继续影响其他业务运行。
第一步查看我们的健康检查系统,这个实例已经处于不健康的状态,所有请求都没响应。
第二步查看Skywalking 链路追踪平台,几乎这个实例的调用全部超时失败。
第三步查看运行日志,发现很多MySQL连接获取超时,服务调用失败等错误。
如下所示:
// 报错1 2021-12-29 14:09:00.222 [http-nio-8030-exec-17] WARN o.s.b.a.j.DataSourceHealthIndicator -DataSource health check failed org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariCP - Connection is not available, request timed out after 176706ms. at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:324) at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.getProduct(DataSourceHealthIndicator.java:122) at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doDataSourceHealthCheck(DataSourceHealthIndicator.java:105) at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doHealthCheck(DataSourceHealthIndicator.java:100) at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:82) // 报错2 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariCP - Connection is not available, request timed out after 112702ms.
第四步同时查看JVM的运行参数,
ps -ef|grep java
输出:
java -jar -Xloggc:/data/logs/micro-xxxx-service-gc-%t.log -XX:metaspaceSize=256m -XX:NativeMemoryTracking=detail -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCCause -Xmn512m -Xms1024m -Xmx1024m micro-xxxx-service.jar
然后排查JVM GC情况,经查看GC日志发现几乎每秒都在进行FullGC,
如下图所示:
经过跟业务和产品确认,我们的用户量和业务量最近没有产生过陡增,也就是一直正常跑的应用突然出现了问题。
那根据FullGC频繁现象,首先怀疑是某个新功能导致内存不释放或直接进入Old区,导致内存一直不释放,最终频繁Full GC问题。
经过排查出错日志点开始向前排查,发现有个全表查询SQL,这个SQL查的表日常数据百万,大致分析是由这个SQL引起的问题。根据SQL进行分析对应的功能,然后跟产品确认,确实这个功能是最近刚刚上线的新功能,然后马上组织产品和研发、测试伙伴确认修改方案,将全表查询改为带条件以及增加分页限制。
个人总结:
- 首先,保留问题现场(运行时堆栈,运行日志),迅速解决影响;
- 监控平台,链路调用平台查看错误点;
- 运行日志快速分析出错点;
- JVM 堆栈、GC情况分析;
- 跟业务和产品确认是否有用户量或业务量陡增,以及确认是否存在新功能上线;
- 结合运行日志异常和JVM堆栈以及GC情况具体分析;
- 找到问题点,快速修复验证,发布。
传送门:
JVM调优- java进程,JVM频繁GC,导致CPU占用、内存占用过高过高定位和排查
JVM-MySQL-Tomcat-服务调用,调优相关
生产稳定:SpringBoot-Admin 微服务监控+健康检查+钉钉告警,附代码配置
-------------欢迎各位留言交流,如有不正确的地方,请予以指正。【Q:981233589】



