面试官:说说服务器CPU 100%的问题如何排查解决

面试官:说说服务器CPU 100%的问题如何排查解决
最新回答
路人

2022-04-03 06:01:32

排查服务器CPU 100%的问题需结合服务器类型(数据库/应用服务器)针对性分析。以下是具体排查和解决思路:

一、数据库服务器常见原因
  1. QPS/TPS飙升:数据库请求量突增。
  2. 新增慢查询SQL:单条或多条SQL执行效率低。
  3. 两者叠加:高并发请求触发慢查询。
排查步骤
  1. 监控对比

    使用云厂商监控(如阿里云、腾讯云)查看当前QPS/TPS,对比历史数据确认是否异常。

  2. 慢查询分析

    检查慢查询日志,定位执行时间过长或频繁调用的SQL。

解决方案
  • QPS/TPS过高:业务层限流或降级,降低数据库压力。
  • 慢查询问题

    回滚最近上线的代码(快速恢复)。

    对非核心功能降级处理。

  • 综合问题:同时采取上述两种措施。
二、应用服务器排查步骤
  1. 定位高CPU进程

    top

  2. 定位高CPU线程

    top -H -p <PID>
  3. 转换线程ID为16进制

    printf "%xn" <TID>
  4. 获取线程堆栈

    jstack <PID> | grep <TID> -A50 >> thread_log.txt

问题定位思路
  1. RUNNABLE状态线程:检查计算密集型代码、循环/递归逻辑或死循环。
  2. GC线程(GC Task Thread):分析GC日志,排查内存泄漏或堆内存配置问题。
  3. BLOCKED状态线程:检查锁竞争(如synchronized或ReentrantLock)。
  4. 单一线程持续高CPU:直接分析该线程代码。
  5. 线程频繁切换:可能是线程池配置不当或线程创建过多。
  6. 死锁检测:搜索堆栈中的deadlock关键字。
解决方案
  1. 计算密集型任务

    优化算法或减少计算量(如改用更高效的数据结构)。

    硬件扩容(如增加CPU核心或分布式处理)。

  2. 死循环问题

    添加可中断标志位(如volatile boolean控制循环退出)。

    限制最大执行次数并添加日志告警。

    // 示例:可中断标志位private volatile boolean running = true;public void stopLoop() { running = false; }// 示例:限制最大执行次数final int MAX_ITERATIONS = 1000;while (count++ < MAX_ITERATIONS && !isTaskDone()) { ... }
  3. 频繁GC问题

    调整JVM堆内存参数(如-Xms、-Xmx)。

    使用工具(如jmap、jstat)分析内存泄漏。

  4. 锁竞争问题

    缩小锁粒度(如分段锁)。

    使用tryLock()避免长时间阻塞。

    // 示例:超时锁获取if (lock.tryLock(100, TimeUnit.MILLISECONDS)) { try { ... } finally { lock.unlock(); }} else { ... }
  5. 死锁问题

    统一加锁顺序(如按对象ID排序加锁)。

    使用无锁数据结构(如ConcurrentHashMap)。

三、总结
  • 数据库服务器:优先通过监控定位QPS或慢查询,结合限流/回滚快速解决。
  • 应用服务器:通过top+jstack定位问题线程,根据堆栈信息针对性优化代码或调整配置。
  • 通用建议

    定期压测,提前发现性能瓶颈。

    完善监控告警(如CPU阈值、慢查询日志)。

通过以上步骤,可系统化排查并解决服务器CPU 100%问题。