专栏名称: 芋道源码
纯 Java 源码分享公众号,目前有「Dubbo」「SpringCloud」「Java 并发」「RocketMQ」「Sharding-JDBC」「MyCAT」「Elastic-Job」「SkyWalking」「Spring」等等
目录
相关文章推荐
芋道源码  ·  关于DeepSeek的最新认知 ·  12 小时前  
芋道源码  ·  年后面试的兄弟们注意了。。。 ·  昨天  
芋道源码  ·  Redis Plus 来了,性能炸裂! ·  昨天  
芋道源码  ·  防止超卖的七种实现 ·  2 天前  
芋道源码  ·  腾讯开源:零代码、全功能、强安全 ORM 库 ·  3 天前  
51好读  ›  专栏  ›  芋道源码

凌晨四点,线上CPU告警,绩效没了!

芋道源码  · 公众号  · Java  · 2025-02-12 14:25

正文

👉 这是一个或许对你有用 的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入 芋道快速开发平台 知识星球。 下面是星球提供的部分资料:

👉 这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、 商城 、支付、工作流、大屏报表、微信公众号、 ERP CRM AI 大模型 等等功能:

  • Boot 多模块架构:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 微服务架构:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 双版本

来源:juejin.cn/post/
7424522247791247394


前言

凌晨4点,我被一阵刺耳的手机铃声惊醒。迷迷糊糊地摸索着手机,屏幕上赫然显示着"线上CPU告警"的字样。瞬间,我的困意全无,取而代之的是一阵冷汗和心跳加速。作为公司核心系统的负责人,我深知这意味着什么——用户体验受损、可能的数据丢失,更糟糕的是,我的年终绩效可能就此化为泡影。

我迅速起身,开始了一场与时间赛跑的故障排查之旅。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

1. 初步诊断:快速定位问题

首先,我登录了服务器,使用top命令查看系统资源使用情况:

$ top

输出显示CPU使用率接近100%,load average远超服务器核心数。这确实是一个严重的问题。

接下来,我使用htop命令获取更详细的进程信息:

$ htop

我发现有几个Java进程占用了大量CPU资源。这些进程正是我们的核心服务。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

2. JVM层面分析:寻找热点方法

确定了问题出在Java应用上,我开始进行JVM层面的分析。首先使用jstat命令查看GC情况:

$ jstat -gcutil [PID] 1000 10

输出显示Full GC频繁发生,这可能是导致CPU使用率高的原因之一。

接着,我使用jstack命令生成线程转储,查看线程状态:

$ jstack [PID] > thread_dump.txt

分析thread dump文件,我发现大量线程处于RUNNABLE状态,执行着相似的方法调用。

为了进一步定位热点方法,我使用了async-profiler工具:

$ ./profiler.sh -d 30 -f cpu_profile.svg [PID]

生成的火焰图清晰地显示了一个自定义的排序算法占用了大量CPU时间。

3. 应用层面优化:重构算法

找到了罪魁祸首,我立即查看了相关代码。这是一个用于大量数据的自定义排序算法,原本设计用于小规模数据,但随着业务增长,它的性能问题暴露无遗。

我迅速重构了算法,使用Java 8的并行流进行优化:

List sortedData = data.parallelStream()
    .sorted(Comparator.comparing(Data::getKey))
    .collect(Collectors.toList());

同时,我添加了缓存机制,避免重复计算:

@Cacheable("sortedData")
public List getSortedData() {
    // 优化后的排序逻辑
}

4. 数据库优化:索引与查询改进

在排查过程中,我还发现了一些低效的数据库查询。使用explain命令分析SQL语句:

EXPLAIN SELECT * FROM large_table WHERE status = 'ACTIVE';

结果显示这个查询导致了全表扫描。我立即添加了合适的索引:

CREATE INDEX idx_status ON large_table(status);

并重写了部分ORM查询,使用更高效的原生SQL:

@Query(value = "SELECT * FROM large_table WHERE status = :status", nativeQuery = true)
List findByStatus(@Param("status") String status);

5. 部署优化:资源隔离

为了防止单个服务影响整个系统,我决定使用Docker进行资源隔离。创建了如下的Dockerfile:

FROM openjdk:11-jre-slim
COPY target/myapp.jar app.jar
ENTRYPOINT ["java""-Xmx2g""-jar""/app.jar"]

并使用Docker Compose进行服务编排,限制了CPU和内存使用:

version: '3'
services:
  myapp:
    build: .






请到「今天看啥」查看全文


推荐文章
芋道源码  ·  关于DeepSeek的最新认知
12 小时前
芋道源码  ·  年后面试的兄弟们注意了。。。
昨天
芋道源码  ·  Redis Plus 来了,性能炸裂!
昨天
芋道源码  ·  防止超卖的七种实现
2 天前
java一日一条  ·  博君一笑
8 年前
陈安之  ·  聊微信的十大禁忌!你知道吗?
7 年前
小鹿情感先生  ·  如何让女生在需要安慰的时候更喜欢你
7 年前