怎么排查Java系统运行缓慢等问题

发布时间:2022-02-28 09:56:28 作者:iii
来源:亿速云 阅读:168
# 怎么排查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        # 网络流量分析

2.2 JVM基础配置验证

// 获取运行时参数
Runtime.getRuntime().availableProcessors(); // 核心数
ManagementFactory.getRuntimeMXBean().getInputArguments(); // JVM参数

2.3 常见配置陷阱


三、JVM性能分析

3.1 内存分析工具

jmap -histo:live <pid>       # 对象直方图
jmap -dump:format=b,file=heap.hprof <pid>  # 堆转储
jstat -gcutil <pid> 1000 5   # GC实时监控

3.2 GC日志分析

# 推荐GC日志参数
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps
-Xloggc:/path/to/gc.log

3.3 常见内存问题

  1. Young GC频繁:-Xmn调整新生代大小
  2. Full GC耗时:检查Old Gen对象引用
  3. MetaSpace溢出:排查动态类生成

四、线程与锁分析

4.1 线程转储分析

jstack <pid> > thread_dump.txt
# 使用VisualVM或fastthread.io在线分析

4.2 锁竞争检测

// 示例:死锁代码
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();
    }
}

4.3 并发优化方案


五、数据库性能排查

5.1 SQL分析工具

-- MySQL慢查询日志
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;

-- 执行计划分析
EXPLN ANALYZE SELECT * FROM large_table WHERE unindexed_column = 'value';

5.2 连接池配置

# Spring Boot配置示例
spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      connection-timeout: 30000
      leak-detection-threshold: 5000

六、外部依赖与IO瓶颈

6.1 HTTP客户端优化

// HttpClient连接池配置
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(50);

6.2 文件IO优化


七、代码级优化建议

7.1 集合使用规范

// 反面案例 - 动态扩容
List<User> users = new ArrayList<>(); 
for(int i=0; i<1e6; i++){
    users.add(getUser(i)); // 触发多次扩容
}

// 优化方案
List<User> users = new ArrayList<>( (int)1e6 );

7.2 流式处理优化

// 低效写法
list.stream()
    .filter(x -> x>10)
    .collect(Collectors.toList())
    .forEach(System.out::println);

// 优化为终端操作
list.stream()
    .filter(x -> x>10)
    .forEach(System.out::println);

八、监控体系建设

8.1 监控指标矩阵

层级 必监控指标 工具示例
JVM GC时间/堆内存/线程数 Prometheus+Grafana
数据库 慢查询/连接数/锁等待 Datadog
外部调用 成功率/TP99/重试次数 SkyWalking

九、典型场景案例

9.1 电商大促场景

现象:秒杀活动开始后系统卡死
根因: 1. 库存查询SQL未走索引 2. 同步锁导致线程堆积 3. Redis连接池耗尽

解决方案: 1. 添加stock_id索引 2. 改用Redis分布式锁 3. 连接池扩容+预热


十、总结与预防措施

10.1 检查清单

  1. [ ] GC日志是否完整记录
  2. [ ] 线程数是否合理限制
  3. [ ] SQL执行计划是否验证

10.2 推荐工具链

”`

(注:此为精简框架,完整8000字版本需扩展各章节案例分析、数据图表、工具截图及具体参数调优建议)

推荐阅读:
  1. Java如何排查问题
  2. 详解JAVA 连等赋值问题

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:Java引用相关内容有哪些

下一篇:怎么制作CLI可能用到的轮子

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》