Java 线上机器 CPU 100 的一次排查过程

news2025/7/7 13:58:43

文章目录

  • 1. 问题发生
  • 2. 数据库连接关闭问题排查
  • 3. 问题的进一步排查
  • 4. 解决方法

1. 问题发生

日常敲代码突然收到生产环境异常告警,线上有一台机器 CPU 使用率飙升到 100 触发扩容,工作群里一下子鸡飞狗跳。 出现问题,首先当然是查看监控和日志,以下是相关现象:

  1. 从监控上看,CPU 飙升的同时,还伴随着大对象的分配和大量 GC

    在这里插入图片描述

  2. 紧接着搜索 Error 日志,发现问题时间点附近只有如下异常,显然是数据库连接关闭后又在连接上执行命令导致。公司有专门的 DBA 团队在维护数据库,直接带着问题去找人就好了

    org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.

2. 数据库连接关闭问题排查

DBA 的反馈是问题时间点附近有多个事务发生了并发更新锁等待,有事务长时间未提交,造成其他等待锁的事务超时,进而导致数据库主动关闭连接,除此之外就没有其他信息可以提供了。

此时排查整个项目代码,不存在多个触发点更新同一组表的情况,排除死锁。结合日志发现发生异常的接口短时间内被多次调用,每次调用都以异常结束,并且耗时都达到 10s 以上。根据操作日志和业务使用方联系上,证实对方使用一项功能时点击按钮没有反应,于是几秒内多次点击,直接导致了线上异常告警。至此,梳理线上故障产生的过程如下:

  1. 使用方点击按钮,发现没有反应(实际上是接口处理慢,没有返回),于是多次点击按钮触发接口调用,每次传过来的参数都一样
  2. 接口处理过程中发起了数据库事务,由于多次调用传入的参数都是一样的,所以最终是操作了同一组表的相同记录,存在并发更新锁的竞争
  3. 由于某些原因,首先发起数据库事务的线程处理缓慢,迟迟没有提交事务,导致其它线程发起的事务一直拿不到锁,直到超时后连接被数据库关闭,再在这个连接上发送命令就报出异常

经过以上梳理,显然造成数据库连接关闭问题的根因是从事务发起到事务提交两个节点之间存在耗时操作,导致事务长时间没有提交。到了这一步,基本锁定案发现场,结合代码和日志发现问题如下:

  1. 异常接口的处理逻辑中存在很多数据库操作,包括了表的更新和插入,事务范围比较大
  2. 业务使用方此次操作导致的数据变更量非常大,除了 10 张表数据更新,还包括了四万条数据的插入。由于四万条数据都是在内存中生成再一次插入数据库的,所以吃内存比较严重,可以和监控显示的大对象分配与频繁 GC 相映证

3. 问题的进一步排查

问题排查至此,似乎根本原因就是大事务,只要拆分事务就能解决。然而这其中依然存在一些疑点:

  1. 数据库插入四万数据是否会慢到 10s 的级别?程序中有打印 SQL 语句的组件,从 SQL 语句执行的日志来看,插入四万条数据其实不到 1s 就返回了
  2. 如果仅仅是数据库执行慢,那顶多也就是网络 IO 耗时,为什么 CPU 会飙到 100

公司基础设施还算完善,线上部署了 Arthas 用于排查问题,为了进一步排查,笔者决定复现问题,并同时使用 Arthas 实时监控程序运行状况。有关于 Arthas 的使用读者可以直接前往 官方传送门,笔者使用 thread -n 8 命令监控最忙的前 8 个线程,多次操作终于发现了 CPU 飙升 100 的罪魁祸首:

  1. 监控显示,最忙的线程的堆栈中正在执行的方法是字符串的匹配和替换,我们知道字符串匹配替换需要使用 CPU 资源
  2. 方法的触发点来自于 SQL 语句打印组件,该组件会切入 MyBatis 执行器,在数据库命令执行返回后打印 SQL,具体实现读者可以参考MyBatis @Intercepts 实现打印 SQL 语句
  3. 结合上一节分析,数据库执行了一条四万数据量的插入命令,SQL 语句庞大无匹,在此基础上通过字符串匹配替换实现 SQL 语句的参数填充,要消耗的 CPU 资源可想而知

4. 解决方法

分析到这里一切豁然开朗,解决方法自然不言而喻。由于 SQL 打印组件有开关配置属性,所以在生产环境改下这个属性关掉 SQL 打印功能,重新发布服务后问题解决,不再复现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/18492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在群晖NAS上搭建导航页_通过Web Station搭建

一、业务需求 1.1、需求说明 我们在使用群晖NAS的过程中,随着时间的推移会安装各种各样的软件内容和管理工具,而这些内容又都是一些网页界面(特别是一些在Docker中搭建的工具)时间久了我们也记不住那么多工具的Web界面地址&#…

激活Windows时出现错误代码0xC004C003怎么办?

Windows是我们最常见的电脑操作系统,那么如果我们在尝试激活Windows时出现错误代码0xC004C003,应该如何解决? 什么是Windows激活错误0xC004C003,出现该错误的原因是什么? Windows操作系统为了抑制盗版软件&#xff0c…

3D建模就业前景如何?加班多吗?值不值得入行

加班其实都还好🤔,因为这个岗位是按照项目进度考核(算钱)的,老手做一个模型要5,6个小时,新手可能需要10个小时,新人刚入行,做东西效率跟不上😰需要加班来弥补是肯定有的事…

SpringMVC-整合详解

SpringMVC-整合详解 MVC 什么是MVC? 它是一种开发模式,它是模型视图控制器的简称。所有的web应用都是基于MVC开发的 M: 模型层,它是模型视图控制器的简称。所有的web应用都是基于MVC开发 V: 视图层,html、javascript、vue等都是视图层,用…

高校实验室设备管理系统设计与实现-计算机毕业设计源码+LW文档

数据库代码: /* Navicat MySQL Data Transfer Source Server : mysql5 Source Server Version : 50562 Source Host : localhost:3306 Source Database : ssmgxsyssbglxthsg3511cg ​ Target Server Type : MYSQL Target Server Versio…

Linux磁盘分区和管理

文章目录一 添加硬盘,创建Linux分区1.首先准备一块新的硬盘2.检查系统是否识别了硬盘3.对磁盘进行分区3-1 创建MBR磁盘分区3-2 创建文件系统3-3 挂载文件系统二 创建交换空间2-1 创建分区2-2 设置分区类型2-3 格式化交换空间2-4 激活交换空间三 删除磁盘的分区3-1 备…

【GPU】Nvidia CUDA 编程高级教程——利用蒙特卡罗法求解近似值(CUDA-Aware MPI)

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…

11.24直播预告 | AIGC,看热闹不如看门道

如果把AI比作既富含能源,又无限神秘的海域,那么AIGC这条近半年内流经学术界和创投圈的支流,也无疑既带来了无数机遇,又蕴藏未知风险。 几天前,将门-TechBeat社区的专题(《AIGC的八大前沿创新》)…

Allegro基本规则设置指导书

Allegro基本规则设置指导书 下面介绍基本规则设置指导书之Analysis Modes 点击set-up-constrains-Modes 调出Analysis Modes,这个是所有DRC的总开关 下面介绍常用的一些开关设置 Design Options (Soldermask) 从上往下 阻焊到阻焊的间距 阻焊到pad和走线间距 阻焊到shape…

leecode #加一#二进制求和

题目描述: 给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外,这个整数不会以零开头。 分析:对数…

简单版的采用前后端分离模式实现SpingBoot新增查询功能

目录 后端代码编写 前端代码编写 首页展示: 新增: 开发工具:IDEA、HbuilderX 技术点:后端:SpringBoot,前端:ElementUIvue,采用前后端分离模式实现。 后端代码编写 目录: 代码…

多线程高并发笔记

一、基础知识 1. 线程打断的三种方法 interrupt() 打断某个线程(其实只是设置一个标志位)isInterrupted() 查询某线程是否被打断过(查询是否设置了标志位)static interrupted() 查询当前线程是否被打断过,并重置打断…

计算机毕业设计ssm+vue基本微信小程序的今日菜谱系统

项目介绍 谈到外出就餐,我们除了怕排队,也怕这家餐厅的服务员不够用,没人为我们点餐,那么一餐饭排队一小时,点餐恐怕也要花个半小时,这样不仅给消费者的用餐体验大打折扣同时也给商家的口碑造成了严重负面的影响,所以开发今日菜谱微信小程序系统是必须也是必然的。 本系统采用微…

vue2 sass 安装及使用

最近在看前端。其一因为手里有个项目uniapp的里面使用了sass,但是有sass报错,其次想自己写个vue2后台,感觉sass写起来科学点。但是……版本这个东西……太费劲了…… vue2-cli集成webpack,使用vue create 项目名后再安装sass相当…

C++程序设计期末考试复习试题及解析 3(自用~)

DDL1.题目及分析1.对象数组的析构顺序2.浅拷贝的隐患delete p 还是 delete[]p ?类似的题,自行查阅3.常数据成员的初始化4.默认构造函数5.cin、cout所属类6.重载7.静态数据成员8.多态8.联编9.内联函数10.引用11.static12.构造Complex类13.静态成员函数14.抽象类15.标…

[一篇读懂]C语言二讲:运算符与表达式

[一篇读懂]C语言二讲:运算符与表达式1. 算术运算符与关系运算符1 运算符分类2 算术运算符及算术表达式3 关系运算符与关系表达式【例】关系运算符的使用。4 运算符优先级2. 逻辑运算符与赋值运算符,求字节运算符1 逻辑运算符与逻辑表达式【例】逻辑运算符…

k8s基于kubectl命令管理资源并分配

文章目录一、资源管理介绍二、资源管理方式1、命令式对象管理2、命令式对象配置3、声明式对象配置一、资源管理介绍 在kubernetes中,所有的内容都抽象为资源,用户需要通过master节点操作资源来管理kubernetes。 (1)kubernetes的本…

数据结构串和数组练习题

串和数组 一 填空题 不包含任何字符(长度为0)的串称为 空串 ;由一个或多个空格(仅由空格符)组成的串称为 空白串。 设S“A;/document/Mary.doc”,则strlen(s) 20 , “/”的字符定位的位置为 3 。 子串的…

Windows内核--CreateProcess到内核NtCreateProcess(2.3)

CreateProcessA vs CreateProcessW A和W后缀代表ANSI和UNICODE版本。早期,Windows为了兼容之前ANSI版本,为了推广UNICODE版本,所以做出了两套API. 注意,并不是所有Windows API都有*A和*W两套,只有API参数包含"字符…

[附源码]java毕业设计社区生鲜电商平台

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…