您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 怎么排查Java系统运行缓慢等问题
## 目录
- [一、问题现象与分类](#一问题现象与分类)
- [二、基础环境检查](#二基础环境检查)
- [三、JVM性能分析](#三jvm性能分析)
- [四、线程与锁分析](#四线程与锁分析)
- [五、数据库性能排查](#五数据库性能排查)
- [六、外部依赖与IO瓶颈](#六外部依赖与io瓶颈)
- [七、代码级优化建议](#七代码级优化建议)
- [八、监控体系建设](#八监控体系建设)
- [九、典型场景案例](#九典型场景案例)
- [十、总结与预防措施](#十总结与预防措施)
---
## 一、问题现象与分类
### 1.1 常见表现形态
- **响应时间延长**:API接口从200ms增加到2s
- **吞吐量下降**:TPS从1000骤降到200
- **资源占用飙升**:CPU持续>90%或内存占用超过80%
- **异常波动**:白天正常但夜间定时变慢
### 1.2 问题分类矩阵
| 问题类型 | 特征指标 | 典型场景 |
|----------------|-------------------------|-----------------------|
| CPU密集型 | CPU利用率>80% | 复杂计算/死循环 |
| IO密集型 | IO等待>30% | 数据库慢查询/日志写入 |
| 内存泄漏 | Old Gen持续增长 | 静态集合缓存 |
| 锁竞争 | 线程BLOCKED状态增多 | 同步方法滥用 |
| 外部依赖瓶颈 | 网络延迟突增 | 第三方API超时 |
---
## 二、基础环境检查
### 2.1 系统资源监控
```bash
# Linux系统检查
top -H -p <java_pid> # 查看进程级资源占用
vmstat 1 5 # 检查CPU/IO/memory上下文切换
sar -n DEV 1 3 # 网络流量分析
// 获取运行时参数
Runtime.getRuntime().availableProcessors(); // 核心数
ManagementFactory.getRuntimeMXBean().getInputArguments(); // JVM参数
jmap -histo:live <pid> # 对象直方图
jmap -dump:format=b,file=heap.hprof <pid> # 堆转储
jstat -gcutil <pid> 1000 5 # GC实时监控
# 推荐GC日志参数
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/path/to/gc.log
jstack <pid> > thread_dump.txt
# 使用VisualVM或fastthread.io在线分析
// 示例:死锁代码
public class DeadLock {
static Object lock1 = new Object();
static Object lock2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock1) {
sleep(100);
synchronized (lock2) {}
}
}).start();
new Thread(() -> {
synchronized (lock2) {
sleep(100);
synchronized (lock1) {}
}
}).start();
}
}
ConcurrentHashMap
替代synchronizedMap
ReadWriteLock
替代重量级锁ThreadLocal
减少竞争-- MySQL慢查询日志
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
-- 执行计划分析
EXPLN ANALYZE SELECT * FROM large_table WHERE unindexed_column = 'value';
# Spring Boot配置示例
spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
leak-detection-threshold: 5000
// HttpClient连接池配置
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(50);
FileChannel
替代传统IOMappedByteBuffer
AsyncAppender
// 反面案例 - 动态扩容
List<User> users = new ArrayList<>();
for(int i=0; i<1e6; i++){
users.add(getUser(i)); // 触发多次扩容
}
// 优化方案
List<User> users = new ArrayList<>( (int)1e6 );
// 低效写法
list.stream()
.filter(x -> x>10)
.collect(Collectors.toList())
.forEach(System.out::println);
// 优化为终端操作
list.stream()
.filter(x -> x>10)
.forEach(System.out::println);
层级 | 必监控指标 | 工具示例 |
---|---|---|
JVM | GC时间/堆内存/线程数 | Prometheus+Grafana |
数据库 | 慢查询/连接数/锁等待 | Datadog |
外部调用 | 成功率/TP99/重试次数 | SkyWalking |
现象:秒杀活动开始后系统卡死
根因:
1. 库存查询SQL未走索引
2. 同步锁导致线程堆积
3. Redis连接池耗尽
解决方案:
1. 添加stock_id
索引
2. 改用Redis分布式锁
3. 连接池扩容+预热
”`
(注:此为精简框架,完整8000字版本需扩展各章节案例分析、数据图表、工具截图及具体参数调优建议)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。