生产问题排查速查手册:Linux 常用命令

封面:生产排查手册

凌晨两点被告警叫醒,登上跳板机,先 ps 还是先 tail?这份手册把生产排查最常用的进程、日志、接口命令固定下来,照着抄就能跑。

本篇你能学到 ​

  • 用 ps aux 与 ps -ef 确认服务进程和父进程
  • 用 zgrep 在按天压缩的日志里查上下文
  • 用 grep -C 5 定位报错前后 5 行线索
  • 用 curl -v 判断网络连通性与请求响应
  • 用 -w "%{http_code}" 在脚本里只取状态码

一、排查总思路:三板斧 ​

1. 固定顺序:进程、日志、接口 ​

生产告警到手,我的固定套路是:

text
定位进程 → 找到日志文件 → 按 key 检索上下文 → 需要时通过 HTTP 请求验证接口

这条顺序的逻辑是先确认对象、再找证据、最后做验证。进程不在,后面两步都白做;进程在但日志有异常,就去日志里找上下文;日志看不出问题,再用接口请求验证服务本身。

2. 三板斧与整机排查层次 ​

从整机到线程,资源类问题的排查层次是先看负载、再定位进程、最后看线程栈。这份手册处理的是业务告警,落到单机上收敛为三段:进程、日志、接口;日志不在本机时,先远程拉取再检索。前者判断机器是否健康,后者判断服务是否正常。

配图

图 1:排查三板斧落地,定位进程、检索日志、验证接口,日志在远端时先拉取

图 1:排查三板斧落地,定位进程、检索日志、验证接口,日志在远端时先拉取

3. 每一步的预期产出 ​

进程这步要拿到 PID 和启动用户,日志这步要拿到报错前后 5 行,接口这步要拿到状态码和响应体。三样凑齐,大多数告警都能定位到具体环节,而不是停在「服务好像有问题」。

二、进程与服务排查 ​

1. 确认进程是否存活 ​

确认目标服务是否在运行、运行在哪个节点上:

bash
# 查找某个进程(比如确认 nginx / java 进程是否存活)
ps aux | grep nginx

预期结果是输出里出现目标进程的 PID、启动用户和启动命令。比如 nginx 一般是一个 master 加若干 worker,只有 master 没有 worker,说明 worker 起不来,问题不在端口而在配置或权限。

2. 常用变体与判读 ​

常用变体有两个,一个看父进程,一个排除 grep 自身:

bash
ps -ef | grep java          # 另一种格式,能看到父进程
ps aux | grep java | grep -v grep   # 排除 grep 自身

ps -ef 的 PPID 列能看出进程由谁拉起,排查「重启后进程反复退出」时特别有用。ps aux 的输出更适合看 CPU、内存占比;管道里 grep 自身也会被匹配到,所以要加 grep -v grep。

正常状态下,列表里只剩真正的 java 进程,PID 稳定,CPU 和内存没有异常飙高。如果 PID 一直在变,说明进程在反复重启,先去日志里找退出原因。

三、日志排查:从目录到上下文 ​

1. 日志位置:先确认目录再搜文件 ​

应用日志通常有约定俗成的目录,我们环境是:

bash
cd /wls/applogs/    # 应用日志根目录,按应用名分目录存放

打开后能直接看到按应用名分的子目录。先确认目录再搜文件,比上来就全盘查找快得多,也不会误碰系统日志。

2. 压缩日志搜索:历史报错用 zgrep ​

线上日志按天滚动压缩(.gz)非常常见,直接 grep 会漏掉历史日志。用 zgrep:

bash
zgrep -C 5 --color=auto "关键字" /path/to/app.log.2026-03-18.gz

zgrep 的参数与 grep 基本一致,区别是它能直接读 .gz。预期结果是压缩包里的命中行照样带上下文打印出来,不用先解压再搜。

3. 普通文本搜索:grep 必带上下文 ​

bash
grep -C 5 --color=auto "关键字" /path/to/app.log

参数说明:

  • -C 5:显示匹配行前后各 5 行上下文,排查问题必加,单看一行日志几乎没有信息量;
  • --color=auto:高亮命中内容,快速定位。

搜索出来的结果应当命中行居中,前后各 5 行调用链或异常栈一起打印。如果异常栈特别长,把 5 调大,先看完整再谈定位。

4. 加强组合:计数、过滤、实时跟踪 ​

常用加强版:

bash
# 统计关键字出现次数(评估影响面)
grep -c "ERROR" app.log

# 多个关键字的排查组合
grep -E "ERROR|Exception" app.log | grep "orderId=123"

# 实时滚动跟踪
tail -f app.log | grep --color=auto "关键字"

grep -c 用来评估影响面,ERROR 出现 200 次和 2 次,处理优先级完全不同。-E 把多个关键字并起来,再串一个业务 key,能快速缩小到某个订单。tail -f 适合复现中的问题,一边操作一边看输出。

这样一轮下来,先拿到影响面数字,再拿到单个订单的完整上下文,最后能实时观察复现过程。

5. 远程拉取:把日志带回本地 ​

本地分析(看 GC 日志、dump 文件等)比在服务器上直接看舒服得多:

bash
scp <user>@<远程主机>:/remote/path/app.log /local/path/

远程路径在前、本地路径在后,执行前先确认两端目录。拉取完成后,文件应完整落到本地目录,大小与远程一致,后续用本地工具慢慢分析。

四、用 curl 验证接口 ​

1. GET 请求:先确认接口活着 ​

排查问题时经常需要直接调用接口验证服务状态,curl 是服务器上最顺手的工具。

bash
curl http://<服务地址>:<端口>/api/v1/users

排查网络连通性问题加 -v,可以看到完整的连接、请求、响应过程:

bash
curl -v http://<服务地址>:<端口>/api/v1/users

预期结果是返回 200 和业务 JSON。加 -v 后能看到 DNS 解析、TCP 连接、请求头、响应头和响应体,卡在哪一步一目了然。如果连 TCP 都没建起来,就不用再怀疑业务代码。

2. POST JSON:改开关、查开关 ​

以调用一个开关接口为例(修改第三方服务可用状态):

bash
curl --location --request POST 'http://<服务地址>:<端口>/communityservice/api/v1/switch/set' \
--header 'Content-Type: application/json' \
--data-raw '{
  "key": "thirdparty:status",
  "status": false
}'

查询类接口同理:

bash
curl --location --request POST 'http://<服务地址>:<端口>/communityservice/api/v1/switch/get' \
--header 'Content-Type: application/json' \
--data-raw '{
  "key": "thirdparty:status"
}'

两个请求的 body 只差一个 status 字段。set 返回成功后,再 get 一次应能看到 thirdparty:status 已经变为 false,确认修改生效,而不是只看 set 的返回码。

3. 参数速查 ​

参数作用
-X / --request指定请求方法(GET / POST / PUT / DELETE)
-H / --header添加请求头(如 Content-Type: application/json)
-d / --data-raw携带请求体
-L / --location跟随 301/302 重定向
-v打印完整请求与响应过程,排查连通性问题必用
-o / -O响应保存到文件
-s静默模式,去掉进度条
-w "%{http_code}"只输出状态码,写脚本判断常用

这张表里最常用的是 -v 和 -w "%{http_code}"。前者排查连通性,后者适合写进脚本做判断,只取状态码,不解析整段响应。

4. 实战提醒:开关要留痕,也要记得恢复 ​

应急类的开关操作,动作要留痕、恢复要记得。建议在故障处理清单里加一条「检查开关状态」,避免故障恢复后服务长期处于降级状态。

做到这一点,每次开关操作都有记录人和时间,复盘时能对上;恢复后开关回到默认值,不留下隐形降级。

常见错误与排错 ​

  • 现象:日志里搜不到昨天的报错。原因:日志已按天压缩成 .gz,grep 不读压缩文件。解法:换成 zgrep,路径直接指到 .gz 文件。
  • 现象:进程列表里混进一条 grep 自己。原因:ps aux | grep java 会匹配到 grep 进程。解法:管道尾部加 grep -v grep。
  • 现象:只看到一行报错,不知道前后发生了什么。原因:搜索时没带上下文参数。解法:加 -C 5,异常栈长就把行数调大。
  • 现象:curl 一直卡住或直接连接失败。原因:只盯着业务返回,没看连接过程。解法:加 -v 看 DNS、TCP、TLS 各阶段停在哪,再确认地址和 端口。
  • 现象:故障恢复了,第三方服务却一直是关闭状态。原因:应急开关改了没恢复,检查清单里也没这一项。解法:开关操作留痕,故障清单固定加一条「检查开关状态」。

本篇小结 ​

  • 排查顺序固定为进程、日志、接口,先确认对象活着,再找原因。
  • 线上日志按天压缩,历史报错要用 zgrep,不要用 grep。
  • grep 必带 -C 5,单看一行日志几乎没有信息量。
  • curl -v 是连通性排查的第一手段,脚本里用 -w 单独取状态码。