字节一面:系统突然变慢了,说说你的具体的排查思路?

👉 欢迎加入小哈的星球,你将获得: 专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍;演示地址:http://116.62.199.48:7070/

  • 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;

  • 专栏阅读地址:https://www.quanxiaoha.com/column

截止目前,累计输出 90w+ 字,讲解图 3713+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有3300+小伙伴加入

图片

这个问题看起来挺常见的,但是非常考验面试者的综合经验和综合技术能力,以及逻辑语言的组织思维。

首先,系统变慢可能有很多原因,比如CPU、内存、磁盘I/O、网络或者应用程序本身的问题。

所以应该从这些方面入手,逐一排查。不过具体步骤该怎么安排呢?

可能应该先检查整体的资源使用情况,然后根据哪个指标异常再深入分析。

比如,先看看CPU使用率是不是很高,如果CPU很高,可能是某个进程占用了太多资源。

这时候可以用top或者htop这样的工具来查看进程的CPU占用情况。

找到占用高的进程后,再进一步分析,比如用strace或者perf来查看系统调用或者性能瓶颈。

当系统突然变慢时,可以按照以下步骤逐步排查问题,结合工具快速定位瓶颈:

整体资源监控(快速定位瓶颈方向)

  • 工具tophtopvmstatdstat

    • Load Average:1/5/15分钟负载。若负载值接近或超过CPU核心数,说明系统过载。

    • %CPU:用户态(us)、内核态(sy)、I/O等待(wa)。若 wa 高,可能是磁盘瓶颈。

    • %MEM 和 Swap:内存不足时,si/so(swap in/out)会频繁变化。

    • 运行 top,观察:

    • vmstat 1:查看上下文切换(cs)、内存交换(si/so)、磁盘块读写(bi/bo)等实时指标。

如果是内存的问题,比如内存不足导致swap频繁使用,系统就会变慢。

这时候可以用free -h或者vmstat来查看内存使用情况,特别是swap的使用情况。

如果发现内存不够,可能需要优化程序的内存使用,或者增加内存。

当系统突然变慢时,可以按照以下步骤逐步排查问题,结合工具快速定位瓶颈:

内存瓶颈

  • 确认内存使用

    • free -h:查看物理内存和Swap使用,若 available 极低,可能触发OOM。

    • vmstat 1:观察 si/so,频繁交换会导致性能下降。

  • 分析内存泄漏

    • pmap -x <PID>:查看进程内存映射。

    • Java应用用 jmap -heap <PID> 或 jstat -gcutil <PID> 观察GC情况。

    • 工具:Valgrind(C/C++)、MAT(Java堆分析)。

磁盘I/O也是一个常见的问题,特别是当有大量读写操作时。可以用iostat或者iotop来监控磁盘的I/O情况,看看是否有进程在频繁读写磁盘。

如果磁盘使用率很高,可能需要检查文件系统是否有问题,或者是否有日志文件过大,数据库查询没优化导致大量磁盘操作。

当系统突然变慢时,可以按照以下步骤逐步排查问题,结合工具快速定位瓶颈:

磁盘I/O瓶颈

  • 查看磁盘负载

    • iostat -x 1:关注 %util(利用率)和 await(I/O等待时间),若接近100%说明磁盘饱和。

    • iotop:定位高I/O进程。

  • 文件系统分析

    • df -h:检查磁盘空间是否耗尽。

    • du -sh /* 逐层查找大文件。

    • lsof +L1:查看被删除但未释放空间的文件(未关闭句柄)。

网络问题也可能导致系统变慢,比如网络带宽被占满,或者有大量TCP连接。

可以用iftop或者nethogs来查看网络流量,确定是哪个进程在占用带宽。

另外,检查是否有大量的TIME_WAIT状态的连接,或者是否有DDoS攻击的情况。

当系统突然变慢时,可以按照以下步骤逐步排查问题,结合工具快速定位瓶颈:

网络瓶颈
  • 带宽与连接数

    • iftop 或 nethogs:查看实时带宽占用。

    • sar -n DEV 1:统计网络接口流量。

  • 连接状态分析

    • netstat -antp 或 ss -s:检查 TIME_WAITCLOSE_WAIT 过多等问题。

    • tcpdump 抓包分析异常流量(如DDoS或异常请求)。

接下来是应用程序层面,比如代码中的死锁、死循环、数据库慢查询等。

可以用jstack(如果是Java应用)来检查线程状态,看是否有死锁。

数据库方面,可以用慢查询日志来分析哪些SQL语句执行时间过长,然后进行优化。

另外,系统日志也很重要,比如/var/log/messages或者dmesg,看看有没有硬件错误或者其他系统级别的错误信息。

具体的步骤顺序。比如,先快速检查CPU、内存、磁盘、网络这四个方面,确定哪里是瓶颈,然后再深入分析相关部分。使用top命令的话,可以按1看各个CPU核心的使用情况,按M按内存排序,按P按CPU排序,这样快速定位问题。

比如,假设运行top后发现某个Java进程CPU使用率特别高,这时候可以用ps -mp [pid] -o THREAD,tid,time查看线程的情况,找到占用高的线程ID,再转换成16进制,用jstack导出线程栈,看看具体在执行什么代码,是否有死循环或者频繁的GC。

应用程序与日志分析

  • 应用日志

    • 查看应用日志(如 tail -f /var/log/app/error.log),搜索异常堆栈或高频错误。

  • JVM分析

    • jstat -gc <PID> 观察GC频率和耗时。

    • jstack <PID> 检查死锁或线程阻塞。

比如Redis的大Key、热Key、慢查询,以及MySQL大事务和慢SQL,特别是在高负载或复杂系统中常见的Redis和MySQL问题。

首先,对于Redis的大Key和热Key,大Key可能导致内存不均、阻塞请求,而热Key可能导致某个实例负载过高。比如使用redis-cli的--bigkeys选项,或者使用monitor命令结合分析工具。另外,热Key可能需要通过缓存拆分、本地缓存或使用Redis的集群模式来分散压力。

然后是Redis的慢查询,需要检查慢查询日志,使用slowlog get命令,并分析原因,比如复杂命令、数据量过大等,并给出优化建议,如拆分命令、使用批量操作等。

对于MySQL,大事务可能导致锁竞争、主从延迟等问题,需要检查长时间运行的事务,使用SHOW PROCESSLIST或查询information_schema.innodb_trx表。慢SQL则需要开启慢查询日志,使用EXPLAIN分析执行计划,优化索引或查询结构。

此外,还需要考虑MySQL的锁和死锁情况,使用SHOW ENGINE INNODB STATUS检查锁信息,以及连接数是否过高等问题,这些都可能影响系统性能。

如果是内存问题,可能要看是否有内存泄漏,用jmap或者VisualVM之类的工具分析堆内存。如果是磁盘I/O问题,可能需要检查是否在大量写日志,或者数据库的索引没优化导致全表扫描。

中间件(如Redis、MySQL)的影响非常关键!实际排查中,这些组件的问题往往是系统变慢的核心原因。以下补充 中间件专项排查 的思路和工具:

中间件专项排查

Redis 问题分析

常见问题:大Key、热Key、慢查询、连接数激增、内存不足等。

  • 大Key检测

    # 扫描大Key(可能阻塞生产环境,建议在从节点执行)
    redis-cli --bigkeys
    • 输出结果中的 Largest stringLargest list 等即为大Key。

    • 风险:大Key导致内存不均、网络阻塞、持久化延迟。

  • 热Key定位

    • 监控工具redis-cli --hotkeys(需开启 maxmemory-policy 为 LFU)。

    • 代理层统计:如 Codis、Twemproxy 可记录Key访问频率。

    • 代码埋点:在客户端记录高频访问的Key。

  • 慢查询分析

    # 查看慢查询日志(需提前配置 slowlog-log-slower-than)
    redis-cli slowlog get 10  # 获取最近10条慢查询
    • 常见原因KEYS *、复杂Lua脚本、大范围HGETALL等。

  • 内存与淘汰策略

    redis-cli info memory  # 查看内存使用详情
    • 关注 used_memorymaxmemoryevicted_keys(因内存不足被淘汰的Key数)。

    • 内存碎片mem_fragmentation_ratio > 1.5 需重启或使用 memory purge(Redis 4+)。

MySQL 问题分析

常见问题:慢SQL、锁竞争、大事务、连接数过载、主从延迟等。

  • 慢SQL排查

    • 开启慢查询日志

      SET GLOBAL slow_query_log = ON;
      SET GLOBAL long_query_time = 1;  -- 定义慢查询阈值(秒)
    • 分析工具

      mysqldumpslow -s t /path/to/slow.log  # 按耗时排序
      pt-query-digest /path/to/slow.log    # Percona Toolkit 详细分析
  • 大事务与锁竞争

    • 查看运行中的事务

      SELECT * FROM information_schema.innodb_trx;  -- 事务详情
      SHOW ENGINE INNODB STATUS;                   -- 锁信息(关注 TRANSACTIONS 段)
    • 长事务监控

      SELECT * FROM sys.session WHERE time > 60;  -- 查询执行超60秒的会话
  • 连接数过载

    SHOW STATUS LIKE 'Threads_connected';  -- 当前连接数
    SHOW VARIABLES LIKE 'max_connections'; -- 最大连接数
    • 若连接数接近 max_connections,需检查连接泄漏或考虑扩容。

  • 主从延迟

    SHOW SLAVE STATUS\G
    • 关注 Seconds_Behind_Master(主从延迟秒数)。

    • 原因:大事务、从库性能差、网络抖动。

消息队列(如Kafka、RocketMQ)
  • 积压监控

    kafka-consumer-groups.sh --describe --group <group_id>  # Kafka查看消费延迟
    • 积压风险:消费者处理能力不足、消息分区不均。

  • 消息堆积处理

    • 扩容消费者实例。

    • 优化消费逻辑(如批量处理、异步化)。

中间件优化案例

场景1:Redis变慢
  • 现象:Redis响应时间波动,CPU使用率不高但延迟高。

  • 排查

  1. redis-cli info stats 查看 total_net_input_bytes 和 total_net_output_bytes,确认是否因大Key导致网络阻塞。

  2. redis-cli monitor 抽样请求,发现频繁执行 HGETALL 操作大Hash。

  • 解决:拆分大Hash为多个小Key,改用 HMGET 按需获取字段。

  • 场景2:MySQL批量插入卡顿
    • 现象:批量插入数据时,系统卡顿,磁盘I/O飙升。

    • 排查

    1. SHOW PROCESSLIST 发现大量 INSERT ... VALUES (...), (...) 语句。

    2. iostat -x 1 显示磁盘 %util 持续100%。

  • 解决

    • 调整批量插入的批次大小(减少单次写入量)。

    • 关闭 autocommit,合并事务提交。

    排查工具补充

    • Redis

      • redis-cli --stat:实时监控Redis状态。

      • redis-rdb-tools:分析RDB文件,统计大Key分布。

    • MySQL

      • pt-query-digest:分析慢查询日志。

      • sysbench:压力测试数据库性能。

    另外,系统变慢还可能是因为最近有更新或者配置变更,这时候可以检查最近的变更记录,或者用系统性能监控工具(如Prometheus+Grafana)查看历史数据,对比变化前后的指标。

    不过,可能还需要考虑外部因素,比如被攻击,或者依赖的服务变慢,导致整个系统卡顿。这时候需要检查网络连接和外部服务状态。

    总结一下,我的思路应该是:

    1. 整体资源监控(top, vmstat, iostat, iftop)

    2. 确定资源瓶颈(CPU、内存、磁盘、网络)

    3. 针对具体瓶颈深入分析(进程、线程、代码)

    4. 检查系统日志和应用程序日志

    5. 中间件(数据库、redis、消息队列)

    6. 考虑外部因素和近期变更

    总之,整个过程需要有条理地逐步缩小问题范围,结合多个工具的数据综合分析,找到根本原因。

    👉 欢迎加入小哈的星球,你将获得: 专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

    • 新项目:《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍;演示地址:http://116.62.199.48:7070/

    • 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;

    • 专栏阅读地址:https://www.quanxiaoha.com/column

    截止目前,累计输出 90w+ 字,讲解图 3713+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有3300+小伙伴加入

    图片

    图片

    图片

    1. 我的私密学习小圈子,从0到1手撸企业实战项目~
    2. SpringBoot 公共字段自动填充的6种神技,开发效率飙升!
    3. 循环中使用 Thread.sleep,代码评审被老板喷了
    4. Java 21 新特性的实践,确实很丝滑!
    最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
    获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。
    PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。
    点“在看”支持小哈呀,谢谢啦
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值