线上Spring CPU 高负载解决思路详解

目录
  • 引言
  • 定位问题
    • 日志搜索
    • 监控看板
    • ThreadDump
    • 优化
  • 事后反思

引言

背景: 在某一天,运营同事突然发现运营看板好几天没有更新数据了, 然后找了过来?!

这里看似抛出了一个问题 ?

但细想一下, 同时暴露了我们对于线上服务的监控未完全覆盖到!!! 这是致命的!!!

当然, 这篇文章先不讨论监控的问题, 后面会推出完善的监控方案

定位问题

问题抛过来了, 那么我们第一步要怎样做呢?

拿到问题的第一步, 先理解题意, 这里有几个关键的信息点

第一 : 好几天, 具体哪一天, 这个后面确认了一个具体的时间点

第二 : 运营看板, 这是重点, 是我们切入问题的关键

好了, 有了这两个关键的信息, 我们接下来就开始定位问题代码了

  • 从功能出发, 定位到未更新的表
  • 通过表来定位到更新数据的代码

通过上面两步找到了问题代码是某个定时任务

日志搜索

这时按照肌肉记忆, 先是看了代码有没有关键点的日志输出, 发现代码开始和结束都有打印日志的操作

顺藤摸瓜,先登录到服务器端, grep一波关键的日志

发现当天的 info.log 没有打印到日志, 这就很奇怪了, 因为这个定时任务的 cron 是每天凌晨1点开始

然后就查了前一天的日志, 发现有打印到开始的日志, 但是没有打印结束的日志

然后再去找看有没有异常的日志, 发现并没有

监控看板

从日志看出了一点不对劲的味道, 但还没有足够的线索定位到具体的问题

这时去查看容器的资源情况

这里观察的是, 在两台容器中, 有一台容器的 cpu 吃得很紧

另外一台却是风平浪静

从这里可以定位到大概的问题了: CPU负载高

那为什么会造成 CPU 跑那么高呢 ?

ThreadDump

当然有很多方案可以定位 CPU 的瓶颈问题,像使用火焰图定位(下一篇会使用到)

但从上面的蛛丝马迹里可以大体定位到是具体的定时任务引起的

这时 threaddump, 并分析了一波线程的运行情况

从整体的报告可以看出有阻塞的线程两个, 同时有百分之四十是在超时等待

再看看具体被阻塞的线程

看起来是数据库查询阻塞

看具体的业务代码

分析一下这条 SQL 的变量

入参只有一个就是 classIds 数组:

  • 数量很小
  • 数量很大
  • 数量为 0

数组的分布情况可以为上面几种

套进去

  • 数量很小, 查询应该很快
  • 数量很大, 查询应该会相对慢一点
  • 数量为 0 呢, if 标签, classIds 数量为 0, 不会 拼接下面的 sql, 也就是会查全表

优化

定位到具体的代码了, 那就是要出优化方案了

做法就是当 classIds 的大小为 0 的时候, 不要扫描全表

这里添加 otherwise 分支, classIds 大小为 0 是 and false

重新部署再观察线上情况, CPU 降了下来

事后反思

为什么会这么久才发现问题? 而且依赖于业务侧发现问题

能不能提前感知问题呢?

想了一下, 我们的监控更多是在监测代码抛出异常, 对于操作系统的资源缺少监控 下一步的优化, 对操作系统资源进行监控

以上就是线上Spring CPU 高负载解决思路详解的详细内容,更多关于线上Spring CPU 高负载的资料请关注我们其它相关文章!

(0)

相关推荐

  • mysql CPU高负载问题排查

    MySQL导致的CPU高负载问题 今天下午发现了一个MySQL导致的向上服务器负载高的问题,事情的背景如下: 在某个新服务器上,新建了一个MySQL的实例,该服务器上面只有MySQL这一个进程,但是CPU的负载却居高不下,使用top命令查询的结果如下: [dba_mysql@dba-mysql ~]$ top top - 17:12:44 up 104 days, 20 min, 2 users, load average: 1.06, 1.02, 1.00 Tasks: 218 total,

  • java面试应用上线后Cpu使用率飙升如何排查

    目录 引言 模拟一个高CPU场景 排查步骤 第一步,使用 top 找到占用 CPU 最高的 Java 进程 第二步,用 top -Hp 命令查看占用 CPU 最高的线程 第三步,查看堆栈信息,定位对应代码 小结 引言 上次面试官问了个问题:应用上线后Cpu使用率飙升如何排查? 其实这是个很常见的问题,也非常简单,那既然如此我为什么还要写呢?因为上次回答的时候我忘记将线程PID转换成16进制的命令了. 所以我决定再重温一遍这个问题,当然贴心的我还给大家准备好了测试代码,大家可以实际操作一下,这样下

  • 基于Java在netty中实现线程和CPU绑定

    目录 简介 引入affinity AffinityThreadFactory 在netty中使用AffinityThreadFactory 总结 简介 使用java thread affinity库我们可以将线程绑定到特定的CPU或者CPU核上,通过减少线程在CPU之间的切换,从而提升线程执行的效率. 虽然netty已经够优秀了,但是谁不想更加优秀一点呢?于是一个想法产生了,那就是能不能把affinity库用在netty中呢? 答案是肯定的,一起来看看吧. 引入affinity affinity

  • 一篇文章学会java死锁与CPU 100%的排查

    目录 01 Java死锁排查和解决 1.啥是死锁? 2.为啥子会出现死锁? 3.怎么排查代码中出现了死锁?[重点来了] 第一个姿势:使用 jps + jstack 第二个姿势:使用jconsole 第三个姿势:使用Java Visual VM 4.如何避免死锁? 02.Java CPU 100% 排查技巧 第一个姿势,步骤有点多,难度四星 第二个姿势,待开发[奸笑脸] 03 推荐两个高效排查问题工具 04 总结 05 彩蛋-另一个姿势 00 本文简介 作为一名搞技术的程序猿或者是攻城狮,想必你应

  • Java多线程导致CPU占用100%解决及线程池正确关闭方式

    简介 情景:1000万表数据导入内存数据库,按分页大小10000查询,多线程,15条线程跑. 使用了ExecutorService executor = Executors.newFixedThreadPool(15) 本地跑了一段时间后,发现电脑CPU逐渐升高,最后CPU占用100%卡死,内存使用也高达80%. 排查问题 Debug 发现虽然创建了定长15的线程池,但是因为数据量大,在For中循环分页查询的List会持续加入LinkedBlockingQueue() 队列中每一个等待的任务,又

  • 线上Spring CPU 高负载解决思路详解

    目录 引言 定位问题 日志搜索 监控看板 ThreadDump 优化 事后反思 引言 背景: 在某一天,运营同事突然发现运营看板好几天没有更新数据了, 然后找了过来?! 这里看似抛出了一个问题 ? 但细想一下, 同时暴露了我们对于线上服务的监控未完全覆盖到!!! 这是致命的!!! 当然, 这篇文章先不讨论监控的问题, 后面会推出完善的监控方案 定位问题 问题抛过来了, 那么我们第一步要怎样做呢? 拿到问题的第一步, 先理解题意, 这里有几个关键的信息点 第一 : 好几天, 具体哪一天, 这个后面

  • Spring循环依赖的解决方法详解

    目录 什么是循环依赖: Spring实例Bean的本质 循环依赖主要场景 什么情况下循环依赖可以被解决 解决方式 说明:spring如何解决循环依赖,是面试中经常问到的题目,今天我们就来分享一下spring是如何解决循环依赖问题的. 什么是循环依赖: 我们先来看看官方文档的说法: 通俗来讲,就是A依赖B或者B依赖A,或者C依赖自己本身,或是三个以上,例如A依赖B,B依赖C,C又依赖A.如下图: Spring实例Bean的本质 Spring在实例化一个bean的时候,是首先递归的实例化其所依赖的所

  • Java跳跃游戏实例真题解决思路详解

    目录 变式题—跳跃游戏 I 一.题目描述 二.思路 三.代码 变式题—跳跃游戏 II 一.题目描述 二.思路 三.代码 变式题—跳跃游戏 I 一.题目描述 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 .数组中的每个元素代表你在该位置可以跳跃的最大长度.判断你是否能够到达最后一个下标. 来源:https://leetcode.cn/problems/jump-game/ 示例: 二.思路 本题可以使用贪心法解决,对每个能到达的位置(可覆盖到的位置),计算其每次能覆盖的最大长度,

  • Java系统的高并发解决方法详解

    一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构.性能的要求都很简单,随着互联网业务的不断丰富,网站相关的技术经过这些年的发展,已经细分到很细的方方面面,尤其对于大型网站来说,所采用的技术更是涉及面非常广,从硬件到软件.编程语言.mysql" target="_blank" title="MySQL知识库">数据库.WebServer.防火墙等各个领域

  • Spring Xml装配Bean的思路详解

    1,概述 在Spring中提供了三种方式来对Bean进行配置: 在xml文件中配置在Java的接口和实现类中配置隐式Bean的发现机制和自动装配原则 这三种方式都经常用到,而且常常会混合使用.这篇先写xml装配Bean. 2,分析bean标签 <bean id="pserson" class="com.xl.spring.xlIoc.beans.Person"> <property name="id" value="1

  • 在Parallel中使用DbSet.Add()发现的一系列多线程问题和解决思路详解

    发现问题 需求很简单,大致就是要批量往数据库写数据,于是打算用Parallel并行的方式写入,希望能利用计算机多核特性加快程序执行速度.想的很美好,于是快速撸了类似下面的一串代码: using (var db = new SmsEntities()) { Parallel.For(0, 1000, (i) => { db.MemberCard.Add(new MemberCard() { CardNo = "NO_" + i.ToString(), Banlance = 0, C

  • java排查一个线上死循环cpu暴涨的过程分析

    问题,打一个页面cpu暴涨,打开一次就涨100%,一会系统就卡的不行了. 排查方法,因为是线上的linux,没有用jvm监控工具rim链接上去. 只好用命令排查: top cpu排序,一个java进程cpu到500%了,什么鬼..... 查到对应java进程 jps || ps -aux | grep 端口 pid=13455 查看进程中线程使用情况 T排序 查看cpu占用time最高的线程编号 top -Hp 13455 有个线程9877 的时间一直在爆涨 获取线程十六进制地址9877 (十六

  • linux下cpu飙高原因排查过程详解

    目录 前言 开始 步骤 排查 前言 cpu飙高是很常见的线上问题,这都不会的话,属实有点拉跨 兄弟萌不用慌,来我教你一套连招 开始 先来个项目,整个api,到时候我们请求/cpu/{count}就能手动拉高cpu,机智鬼~ @GetMapping("/cpu/{count}") public long cpuTest(@PathVariable("count") long count) { long number = 0; for (int i = 0; i <

  • Spring Boot 多数据源处理事务的思路详解

    目录 1. 思路梳理 2. 代码实践 2.1 案例准备 2.2 开始整活 LoadDataSource.java 3. 总结 首先我先声明一点,本文单纯就是技术探讨,要从实际应用中来说的话,我并不建议这样去玩分布式事务.也不建议这样去玩多数据源,毕竟分布式事务主要还是用在微服务场景下. 好啦,那就不废话了,开整. 1. 思路梳理 首先我们来梳理一下思路. 在上篇文章中,我们是一个微服务,在 A 中分别去调用 B 和 C,当 B 或者 C 有一个执行失败的时候,就去回滚.B 和 C 都是调用远程的

随机推荐