经验案例

1.cpu 利用率高如何排查

解决思路:

  • 定位到占用 CPU 高的进程 pid,确定 pid 对应的进程启动命令
    • ll /proc/{PID}/exe
    • ps -aux | grep {PID}
  • 如果是 java 应用,可进一步查看线程占用资源情况
    • ps -mp {PID} -o THREAD,tid,time。其中 TID 为线程ID
    • jstack -l {PID} > jstack.log。通过 jstack 获取占用资源异常的线程栈,暂时保存的文件中,方便查看
    • jstat -gcutil {PID} 3s。查看进程 GC 持续变化情况
    • jmap -dump:format=b,file=filename {PID}。导出内存对象,会触发 fullgc
  • java 应用可直接用 jps 查看 pid 和启动参数
    • jps -mlv

2.查看端口号占用情况

  • netstat。
    • 查看所有监听的端口号:netstat -ano
    • 查看 3600 是否被占用:netstat -ano | grep 3600
  • lsof。如查看 3600 是否被占用:lsof -i:3600
  • ss。列出所有监听的 tcp 端口号:ss -ltnp

3.磁盘满了

解决思路:

  • 查看服务器挂载的磁盘使用率
  • 查看满了的磁盘,是被什么占满的?
  • 处理磁盘占满问题。
    • 常见的如日志文件过大,用户上传、下载的临时文件在磁盘上没有删除等,这些都可以手动删除
    • 如果是不能删除的场景,需要重新挂载磁盘,迁移数据,配置应用的数据存储位置到新的磁盘目录。

相关命令

  • df -h。查看磁盘使用率
  • du -sh {DIR}。查看指定目录的文件或文件夹占用体积

4.接口请求超时或503

解决思路:

  • 查看日志,找到超时异常日志,获取异常发生的精确时间。
  • 没找到。继续寻找 nginx 或负载均衡日志,判断请求是否发送到了服务器,是不是在网关层就挂掉了。
    • 比如运维更改了网络配置,调整了服务域名而前端未做调整,阿里云负载均衡请求超时最大配置为 2min
  • 找到了。寻找上下文。如果异常日志中有 traceId、或者根据请求参数如 xxId 检索日志,获取请求在执行过程中的上下文
    • 找到上下文,根据应用处理请求的代码逻辑,寻找请求超时的原因
      • 有长耗时的处理逻辑。请求mysql、redis,或调用外部接口超时。处理逻辑本身就比较耗时,如导出数据
      • 逻辑异常。代码内在无限循环
    • 没有找到上下文,判断请求是否进入应用的处理请求逻辑,是不是没有进入才导致没有日志
  • 查看服务器监控信息,获取异常发生的时间点有没有异常信息
    • CPU、内存、网络、磁盘等抖动
    • JVM 监控:GC。是否是发生了长时间的 GC

5.发生OOM如何排查

解决思路:

  • 查看日志,找到 OOM 异常,获取异常发生的堆栈和时间,找到触发异常的代码,分析代码是否有触发 OOM 的潜在可能
  • 查看服务器监控,获取异常发生的时间点有没有异常信息
    • CPU、内存、网络、磁盘等抖动
    • JVM 监控
      • GC。是否有 fullgc,是否有长时间的 gc,是否 gc 后出现回收不理想的现象
      • 线程。服务器线程数是否异常。Java 线程是 linux 线程,每个线程会占据一定资源,过多的线程会占据大量内存资源,导致应用内存不足
  • 查看服务器有没有配置oom异常时,dump 内存的jvm参数。如果配置了,可以分析一下 jvm内存,查看哪些对象无法回收

6.线程池拒绝异常

线程池埋点。

7.JDBC连接池异常。无法获取

linux 命令

top

top 命令是 Linux 系统中常用的性能分析工具,可以实时显示系统中各进程的资源占用情况。

# top [-n] [-d] 

# 如每 5 秒统计一次各进程相关信息:
top -d 5

[!NOTE]

  • [-n]:只在开始时显示一次各字段名称。
  • [delay]:刷新时间间隔。如果不指定,只显示一条结果。
  • [count]:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。

在 top 命令执行过程中,可以使用一些交互命令:

  • shift + p。对 CPU 使用率进行倒序排列,方便定位系统中占用 CPU 较高的进程
  • shift + m。对系统内存使用情况进行排序
  • 1。如果有多核 CPU,数字键 1 可以显示每核 CPU 的负载状况
  • k。输入 k 后,输入想要终止的进程 pid,按 Enter 键可杀死进程

根据 pid 查看进程对应的程序文件:

ll /proc/{PID}/exe

# 比如 pid 对应为 10086
ll /proc/10086/exe

htop

待定

vmstat

# vmstat [-n] [delay [count]] 

# 使用 vmstat 每 1 秒统计一次各进程的 CPU 使用情况
vmstat -n 1

[!NOTE]

  • [-n]:只在开始时显示一次各字段名称。
  • [delay]:刷新时间间隔。如果不指定,只显示一条结果。
  • [count]:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。

显示结果主要字段说明

  • r:表示系统中CPU等待处理的线程。一个CPU每次只能处理一个线程,所以该数值越大,通常表示系统运行越慢。
  • us:用户模式消耗的CPU时间百分比。该值较高时,说明用户进程消耗的CPU时间比较多。如果该值长期超过50%,则需要对程序算法或代码等进行优化。
  • sy:内核模式消耗的CPU时间百分比。
  • wa:I/O等待消耗的CPU时间百分比。该值较高时,说明IO等待比较严重,这可能是磁盘大量作随机访问造成的,也可能是磁盘性能出现了瓶颈。
  • id:处于空闲状态的CPU时间百分比。如果该值持续为0,同时sy是us的两倍,则通常说明系统面临CPU资源短缺。