你应该知道的那些生产问题排查技巧和方式

好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受.

  • 本文系统地梳理了线上问题排查所需的关键命令,这些命令涵盖多个维度,是Java开发者诊断生产环境各类问题的有力工具。在实际操作中,通常需要组合使用这些命令,构建起系统性的排查流程。同时,成功而高效的排查工作不仅依赖于对命令的熟练掌握,更需要对Java应用架构、JVM原理及操作系统机制有深入理解。建议开发者们在日常工作中熟悉这些命令,并在非生产环境多加练习,同时结合完善的监控和日志体系,使问题排查更加高效。

一、系统资源监控

(一)top命令:实时掌控系统进程

  • 命令格式

    • 基本使用:top

    • 按内存排序:top -o %MEM

    • 只查看特定用户的进程:top -u java_user

    • 监控特定进程:top -p $(pgrep -d',' java)

  • 解释说明:top命令用于实时监控系统进程。在排查性能问题时,可通过查看CPU使用率(%CPU)、内存使用率(%MEM)、运行时间(TIME+)等指标,快速定位资源占用异常的进程。

  • 应用场景:当系统整体响应变慢,初步判断是CPU或内存资源紧张时,使用此命令查看哪些进程占用了过多资源。

(二)htop命令:增强型系统监控

  • 命令格式htop

  • 解释说明:htop是比top更友好的监控工具,支持鼠标操作,能清晰展示每个CPU核心的使用情况,适合多核系统的监控。

  • 应用场景:在多核服务器上,通过htop可以直观地看到各个核心的负载情况,便于快速判断是否存在单核过载或多个核心未被充分利用等问题。

(三)vmstat命令:系统资源统计分析

  • 命令格式:每2秒输出一次,共10次:vmstat 2 10

  • 解释说明:该命令统计系统资源使用情况。重点关注r(运行队列)、b(阻塞进程)、si/so(交换区使用)、us/sy(用户CPU/系统CPU),以此判断系统是CPU密集型还是IO密集型负载。

  • 应用场景:当需要全面了解系统资源的整体使用情况,包括内存、CPU和IO等各个方面时,使用此命令进行综合分析。

(四)free命令:内存使用详情

  • 命令格式

    • 显示可读格式:free -h

    • 每3秒更新一次:free -h -s 3

  • 解释说明:用于查看系统内存使用情况,特别是检查可用内存(available)是否充足,以及swap分区的使用情况是否正常。

  • 应用场景:当系统出现内存不足的征兆,如响应延迟增加或频繁GC时,用此命令查看内存的具体分配和使用情况。

(五)iostat命令:IO性能评估

  • 命令格式:查看设备IO统计,每2秒一次,共5次:iostat -xd 2 5

  • 解释说明:iostat用于监控系统IO设备的使用情况。重点关注%util(设备利用率)、r/s和w/s(读写操作数)、await(IO等待时间),帮助判断IO是否成为系统性能瓶颈。

  • 应用场景:当系统响应变慢,怀疑是磁盘IO性能问题时,通过此命令查看磁盘的读写性能指标,判断是否存在IO瓶颈。

(六)其他工具:综合考量

除了上述工具,工具如lsof可用于查看进程打开的文件和网络连接,排查文件描述符泄露问题;uptime命令查看系统负载;sar用于查看系统活动报告;mpstat查看多处理器统计;dmesg查看内核消息;strace跟踪系统调用等。

二、JVM监控与诊断

(一)jps命令:Java进程查找

  • 命令格式

    • 列出简单进程信息:jps

    • 列出完整的包名和进程参数:jps -lvm

  • 解释说明:用于列出系统中所有Java进程,是排查Java问题的起点,首先需要确定目标Java进程的PID。

  • 应用场景:当需要对Java应用进行诊断时,先通过此命令获取目标应用的进程ID。

(二)jstat命令:JVM统计信息监控

  • 命令格式

    • 监控GC情况,每1000毫秒一次,共10次:jstat -gc [pid] 1000 10

    • 查看类加载情况:jstat -class [pid]

    • 查看JIT编译情况:jstat -compiler [pid]

  • 解释说明:用于监控JVM的GC、类加载和JIT编译等关键统计信息。重点关注GC频率、GC耗时、老年代空间使用情况,判断是否存在GC问题。

  • 应用场景:当Java应用出现响应缓慢、卡顿等现象,怀疑与JVM的GC或类加载等问题相关时,使用此命令进行监控。

(三)jmap命令:内存映射与堆转储

  • 命令格式

    • 查看堆内存使用概况:jmap -heap [pid]

    • 查看对象统计信息:jmap -histo [pid] | head -20

    • 生成堆转储文件:jmap -dump:format=b,file=heap_dump.hprof [pid]

  • 解释说明:jmap用于查看JVM堆内存的使用情况,分析内存中大对象,检查是否存在内存泄漏。必要时生成堆转储文件,供后续详细分析。

  • 应用场景:当怀疑Java应用存在内存泄漏或内存使用异常时,先用此命令查看堆内存概况,若发现问题迹象,再生成堆转储文件进行深入分析。

(四)jstack命令:线程堆栈分析

  • 命令格式

    • 生成线程堆栈快照:jstack [pid] > thread_dump.log

    • 包含锁信息的线程转储:jstack -l [pid]

    • 检测死锁:jstack -F [pid] | grep -A 30 "Found.*deadlock"

  • 解释说明:用于生成Java进程的线程堆栈快照,查找BLOCKED状态的线程,分析线程间锁竞争,排查死锁或线程挂起问题。

  • 应用场景:当Java应用出现线程阻塞、死锁或响应缓慢等问题时,通过此命令获取线程堆栈信息,分析线程状态和锁情况。

(五)jinfo命令:JVM参数查看与修改

  • 命令格式

    • 查看所有JVM参数:jinfo -flags [pid]

    • 查看特定参数值:jinfo -flag MaxHeapSize [pid]

    • 动态修改某些参数:jinfo -flag +HeapDumpOnOutOfMemoryError [pid]

  • 解释说明:用于查看和动态修改JVM的参数配置。确认关键参数是否正确配置,必要时动态调整。

  • 应用场景:当需要查看Java应用的JVM参数配置是否合理,或在运行时动态调整某些参数以优化性能时,使用此命令。

(六)jcmd命令:多功能JVM诊断

  • 命令格式

    • 列出所有可用命令:jcmd [pid] help

    • 查看JVM版本信息:jcmd [pid] VM.version

    • 执行GC:jcmd [pid] GC.run

    • 生成堆转储:jcmd [pid] GC.heap_dump filename=heap.hprof

    • 生成线程转储:jcmd [pid] Thread.print

  • 解释说明:jcmd是一个多功能工具,可以替代多个单一功能的JDK工具,简化问题排查流程。

  • 应用场景:在JVM诊断过程中,需要执行多种操作,如查看版本、触发GC、生成堆转储和线程转储等时,使用此命令代替多个工具。

(七)jhat命令:堆转储分析

  • 命令格式:分析堆转储文件:jhat heap_dump.hprof,然后访问http://localhost:7000查看分析结果。

  • 解释说明:用于分析堆转储文件,在浏览器中查看对象实例、引用关系,找出可能的内存泄漏点。

  • 应用场景:当生成堆转储文件后,需要进一步分析其中的对象信息和引用关系时,使用此命令启动分析服务。

(八)arthas和btrace:动态诊断利器

  • Arthas:阿里开源的Java诊断工具,提供丰富的分析能力,如dashboard查看系统概况、trace跟踪方法执行、jvm查看JVM信息等。

  • BTrace:在不重启应用的情况下,动态跟踪Java方法的执行情况。

(九)jprofiler和java-flight-recorder:深度性能分析

  • JProfiler:用于更深入的性能分析,包括CPU热点、内存泄漏、线程分析等。

  • Java Flight Recorder (JFR):收集JVM运行时的详细信息,用于后续分析和性能优化。启动记录:jcmd [pid] JFR.start duration=60s filename=recording.jfr,检查状态:jcmd [pid] JFR.check,停止记录:jcmd [pid] JFR.stop

三、网络相关检测

(一)netstat命令:网络连接状态查看

  • 命令格式

    • 查看所有TCP连接:netstat -ant

    • 查看监听端口:netstat -tnlp

    • 查看特定进程的网络连接:netstat -anp | grep [pid]

  • 解释说明:用于查看系统的网络连接状态,包括连接数、端口占用情况等。

  • 应用场景:当需要检查Java应用的网络连接情况,如连接数是否过多、端口是否被占用等时,使用此命令。

(二)ss命令:高效socket统计

  • 命令格式

    • 显示所有TCP连接:ss -ta

    • 查看连接统计:ss -s

    • 查看特定端口连接:ss -tn sport = :8080

  • 解释说明:比netstat更高效,适合连接数较多的系统,可以快速统计各种连接状态。

  • 应用场景:在高并发网络环境中,快速查看网络连接状态和统计信息时,此命令效率更高。

(三)lsof命令:文件与网络连接查看

  • 命令格式

    • 查看进程打开的所有文件:lsof -p [pid]

    • 查看特定端口使用情况:lsof -i:8080

    • 查看所有网络连接:lsof -i

  • 解释说明:查看进程打开了哪些文件和网络连接,可用于排查文件描述符泄露问题。

  • 应用场景:当怀疑Java进程存在文件描述符泄露,或需要查看其网络连接情况时,使用此命令。

(四)ping命令:网络连通性测试

  • 命令格式

    • 基本使用:ping www.example.com

    • 限制发送次数:ping -c 5 www.example.com

  • 解释说明:用于测试与目标主机的网络连通性和延迟情况。

  • 应用场景:当需要检查Java应用服务器与外部服务(如数据库、消息队列等)的网络连通性时,使用此命令。

(五)curl命令:HTTP请求测试

  • 命令格式

    • 简单GET请求:curl http://localhost:8080/api/status

    • 带超时控制的请求:curl --connect-timeout 5 -m 10 http://api.example.com

    • POST请求:curl -X POST -d '{"name":"test"}' -H "Content-Type: application/json" http://localhost:8080/api/users

  • 解释说明:用于测试HTTP服务的响应情况,检查响应码、响应时间和响应内容。

  • 应用场景:当需要验证Java应用的HTTP接口是否正常工作,或测试其响应性能时,使用此命令。

(六)tcpdump命令:网络数据包分析

  • 命令格式

    • 捕获特定端口的数据包:tcpdump -i any port 8080 -n

    • 捕获特定主机的数据包:tcpdump host 192.168.1.100

    • 保存数据包到文件:tcpdump -i any -w capture.pcap

  • 解释说明:用于捕获和分析网络数据包,排查网络协议相关问题,特别是网络延迟和连接重置问题。

  • 应用场景:当Java应用出现网络通信异常,如请求超时、响应错误等,需要分析网络数据包时,使用此命令。

(七)traceroute命令:路由跟踪

  • 命令格式:基本使用:traceroute www.example.com

  • 解释说明:用于跟踪网络路由,排查网络路由问题,确定网络延迟出现在哪个环节。

  • 应用场景:当Java应用访问外部服务出现延迟,需要检查网络路径上的延迟情况时,使用此命令。

四、日志与文件分析

(一)tail命令:日志实时查看

  • 命令格式

    • 实时查看日志:tail -f app.log

    • 显示最后100行:tail -n 100 app.log

    • 从第1000行开始显示:tail -n +1000 app.log

  • 解释说明:用于实时监控日志文件的输出,是排查问题的基础操作。

  • 应用场景:当需要实时查看Java应用的日志输出,监控其运行状态和错误信息时,使用此命令。

(二)grep命令:文本搜索

  • 命令格式

    • 搜索数据志:grep "ERROR" app.log

    • 显示匹配行的前后5行:grep -A 5 -B 5 "OutOfMemoryError" app.log

    • 递归搜索多个文件:grep -r "Connection refused" /var/log/

  • 解释说明:用于快速定位日志中的特定文本信息,如错误日志、特定关键词等。

  • 应用场景:当需要在大量日志文件中快速找到特定的错误信息或关键词时,使用此命令。

(三)awk命令:文本处理与统计

  • 命令格式

    • 提取特定列:awk '{print $1, $4}' access.log

    • 统计HTTP响应码分布:awk '{print $9}' access.log | sort | uniq -c | sort -nr

    • 计算平均响应时间:awk '{sum+=$10; count++} END {print sum/count}' access.log

  • 解释说明:对日志文件进行结构化处理和统计分析,提取关键信息。

  • 应用场景:当需要对日志文件进行深入分析,如统计访问次数、计算平均响应时间等时,使用此命令。

(四)sed命令:文本替换与提取

  • 命令格式

    • 替换文本:sed 's/ERROR/CRITICAL/g' app.log

    • 只显示特定行范围:sed -n '1000,2000p' app.log

  • 解释说明:用于处理和转换日志文本,如替换特定内容、提取特定行范围等。

  • 应用场景:当需要对日志文件中的某些内容进行替换,或提取特定行范围进行分析时,使用此命令。

(五)find命令:文件查找

  • 命令格式

    • 查找大文件:find / -type f -size +100M

    • 查找最近修改的文件:find /var/log -mtime -1 -type f -name "*.log"

    • 查找并删除老旧日志文件:find /var/log -name "*.log" -mtime +30 -exec rm {} ;

  • 解释说明:用于查找文件系统中的特定文件,如大文件、最近修改的文件等。

  • 应用场景:当需要查找占用磁盘空间大的文件,或查找最近修改过的配置文件等时,使用此命令。

(六)du命令:磁盘使用统计

  • 命令格式

    • 查看目录大小:du -sh /var/log

    • 按大小排序显示子目录:du -h --max-depth=1 /var | sort -hr

  • 解释说明:用于统计磁盘空间的使用情况,找出占用空间大的目录。

  • 应用场景:当系统出现磁盘空间不足时,通过此命令查看各目录的大小,定位空间占用过大的目录。

五、进程管理

(一)ps命令:进程状态查看

  • 命令格式

    • 查看所有进程:ps aux

    • 查看特定用户的进程:ps -u tomcat

    • 按CPU使用率排序:ps aux --sort=-%cpu | head -10

    • 按内存使用率排序:ps aux --sort=-%mem | head -10

  • 解释说明:用于查看系统中进程的状态和资源使用情况。

  • 应用场景:当需要查看系统中所有进程的运行状态,或找出CPU、内存使用率较高的进程时,使用此命令。

(二)pstree命令:进程树结构展示

  • 命令格式

    • 显示进程树:pstree

    • 显示特定进程的进程树:pstree -p [pid]

  • 解释说明:以树状结构显示进程之间的父子关系,便于理解进程的层级结构。

  • 应用场景:当需要了解Java进程及其子进程的关系,排查守护进程和子进程问题时,使用此命令。

(三)kill命令:进程信号发送

  • 命令格式

    • 正常终止进程:kill [pid]

    • 强制终止进程:kill -9 [pid]

    • 生成Java线程转储:kill -3 [java_pid]

  • 解释说明:用于向进程发送信号,终止异常进程或触发特定行为(如生成线程转储)。

  • 应用场景:当需要终止异常的Java进程,或触发Java进程生成线程转储进行分析时,使用此命令。

(四)pkill命令:按名称终止进程

  • 命令格式

    • 终止特定名称的进程:pkill java

    • 向所有Java进程发送SIGTERM信号:pkill -15 java

  • 解释说明:根据进程名称批量终止进程。

  • 应用场景:当需要快速终止所有同名的Java进程时,使用此命令。

(五)pgrep命令:进程ID查找

  • 命令格式

    • 查找Java进程ID:pgrep java

    • 查找并显示命令行:pgrep -a java

  • 解释说明:用于查找特定进程的PID,便于后续的监控和分析。

  • 应用场景:当需要获取Java进程的PID时,使用此命令。

六、数据库相关操作

(一)mysqladmin命令:MySQL服务器管理

  • 命令格式

    • 查看MySQL状态:mysqladmin -u root -p status

    • 查看进程列表:mysqladmin -u root -p processlist

    • 查看变量状态:mysqladmin -u root -p variables

  • 解释说明:用于管理MySQL服务器,查看服务器状态、进程列表和配置变量。

  • 应用场景:当需要检查MySQL服务器的运行状态和配置,监控连接数和进程情况时,使用此命令。

(二)mysqlshow命令:MySQL数据库信息查看

  • 命令格式

    • 显示所有数据库:mysqlshow -u root -p

    • 显示特定数据库的表:mysqlshow -u root -p database_name

  • 解释说明:用于查看MySQL数据库的结构和表信息。

  • 应用场景:当需要快速了解MySQL数据库的结构和表信息时,使用此命令。

(三)pg_stat_activity视图:PostgreSQL活动查询

  • 命令格式(在psql中执行)

    • 查看活动连接:SELECT * FROM pg_stat_activity;

    • 查看长时间运行的查询:SELECT pid, now() - query_start AS duration, query FROM pg_stat_activity WHERE state = 'active' ORDER BY duration DESC;

  • 解释说明:用于查看PostgreSQL数据库中的活动连接和正在执行的查询,找出长时间运行的查询。

  • 应用场景:当PostgreSQL数据库响应变慢,需要检查当前正在执行的查询,找出潜在的长时间运行查询时,使用此视图。

(四)redis-cli命令:Redis客户端操作

  • 命令格式

    • 连接Redis服务器:redis-cli

    • 监控Redis命令:redis-cli monitor

    • 获取统计信息:redis-cli info

  • 解释说明:用于连接和操作Redis服务器,监控命令执行,获取服务器状态信息。

  • 应用场景:当需要检查Redis服务器的状态,监控命令执行情况,排查缓存相关问题时,使用此命令。

七、容器与微服务管理

(一)docker命令:容器操作

  • 常用子命令

    • 查看运行中的容器:docker ps

    • 查看所有容器(包括已停止的):docker ps -a

    • 查看容器日志:docker logs [container_id]

      • 实时查看日志:docker logs -f [container_id]

      • 显示最近的100行日志:docker logs --tail 100 [container_id]

    • 查看容器资源使用情况:docker stats

      • 查看特定容器的资源使用:docker stats [container_id]

  • 解释说明:用于管理Docker容器,包括查看容器状态、日志和资源使用情况。

  • 应用场景:在容器化部署的Java应用环境中,通过这些命令查看容器的运行状态、日志输出和资源使用情况,排查容器内部问题。

(二)kubectl命令:Kubernetes集群管理

  • 常用子命令

    • 获取所有Pod状态:kubectl get pods

    • 查看Pod详细信息:kubectl describe pod [pod_name]

    • 查看Pod日志:kubectl logs [pod_name]

    • 进入Pod内执行命令:kubectl exec -it [pod_name] -- /bin/bash

    • 查看节点资源使用:kubectl top nodes

    • 查看Pod资源使用:kubectl top pods

  • 解释说明:用于在Kubernetes集群中管理Pod和其他资源,查看资源状态、日志和资源使用情况。

  • 应用场景:在Kubernetes环境中部署的Java应用出现问题时,通过这些命令查看Pod的状态、日志和资源使用情况,排查集群中的问题。

八、线上问题排查思路与方法

(一)快速定位问题类型

  • CPU问题排查路径topjstackperf/JFR

  • 内存问题排查路径freejmapjhat/MAT

  • 磁盘问题排查路径dfdulsof/find

  • 网络问题排查路径netstattcpdumpwireshark

  • 应用异常排查路径jpslogsjstackarthas

(二)常见问题排查技巧

  • CPU使用率高

    • 查找占用CPU高的进程:top -c

    • 如果是Java进程,生成线程转储:jstack [pid] > thread_dump.log

    • 查找占用CPU高的线程:ps -mp [pid] -o THREAD,tid,time | sort -rk 3

    • 将线程ID转为16进制:printf "%x\n" [tid]

    • 在线程转储中查找该线程:grep -A 30 [hex_tid] thread_dump.log

  • 内存泄漏

    • 查看堆内存使用情况:jmap -heap [pid]

    • 生成多个堆转储,比较对象增长:jmap -dump:format=b,file=heap1.hprof [pid](等待一段时间后再次生成)

    • 使用MATjhat分析堆转储:jhat heap2.hprof

  • 频繁GC

    • 监控GC情况:jstat -gc [pid] 1000

    • 开启GC日志:java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log

    • 分析GC日志(使用GCViewerGCEasy等工具)

  • 响应缓慢

    • 查看系统负载:uptime

    • 查看网络连接情况:netstat -ant | grep ESTABLISHED | wc -l

    • 查看线程状态:jstack [pid] | grep -c "java.lang.Thread.State"

    • 使用Arthas进行方法追踪:trace com.example.SlowService slowMethod

  • 磁盘空间不足

    • 查看磁盘使用情况:df -h

    • 查找大文件:find / -type f -size +100M -exec ls -lh {} ;

    • 查看目录大小:du -sh /*

    • 清理日志文件:find /var/log -name "*.log.*" -mtime +7 -delete

九、总结

在实际的线上问题排查过程中,通常需要组合使用上述各类命令,形成系统性的排查流程。成功的线上问题排查不仅依赖于对命令的熟练使用,更需要对Java应用架构、JVM原理和操作系统机制有深入的理解。建议开发者们在日常工作中熟悉这些命令,并在非生产环境多加练习,同时结合完善的监控和日志体系,使问题排查更加高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值