测试环境出问题的时候,最耗时间的不是“修”,是“不知道从哪开始看”。
页面 502 了,第一反应是重启。接口超时了,第一反应还是重启。重启能解决一部分问题,但它掩盖了“为什么出问题”,下一次换个模块,同样的流程再走一遍。
下面这 20 条命令,按排查顺序排好了。不是让你背,是让你在卡住的时候,知道先敲哪一条。
第一组:先判断“哪一层出了问题”(4 条)
环境问题最怕一上来就钻细节。先用这四条把范围缩小。
- curl -o /dev/null -s -w "dns:%{time_namelookup} conn:%{time_connect} total:%{time_total}\n"
接口慢的时候,先用它拆时间花在哪。time_connect 高说明建连慢,网络或服务端忙;time_total 远高于 time_connect,说明服务端处理慢。这一步区分“网络问题”和“应用问题”,比直接上服务器翻日志快得多。
- systemctl status <服务名>
页面 502、接口连不上,先确认服务是不是活着。输出里 active (running) 和 inactive (dead) 一眼就能分辨。如果服务反复重启,status 里会显示最近几次退出码,比猜有用。
- journalctl -u <服务名> -n 100 --no-pager
服务挂了,但不知道为什么。journalctl 直接拉这个服务的最近 100 行日志,不用去 /var/log 下面翻文件。常见的关键错误——端口被占、配置文件语法错、权限不足——大概率在前几十行里。
- ss -lntp
看这台机器上到底有哪些端口在监听、分别被哪个进程占着。如果服务应该监听 8080,但 ss -lntp 里根本没有 8080,说明服务没起来或者绑错了地址。如果 8080 被别的进程占了,ss 会直接告诉你 PID。
第二组:端口和进程,排查“连不上”(4 条)
服务活着但连不上,问题通常在端口或进程这一层。
- ss -lntp | grep :<端口号>
只看某一个端口。比 netstat 快,输出也更干净。如果端口在监听,但地址是 127.0.0.1:8080 而不是 0.0.0.0:8080,说明服务只绑了本地回环,外部访问不到。
- lsof -i :<端口号>
ss 告诉你“谁在监听”,lsof 告诉你“这个进程还打开了什么”。排查端口冲突的时候,lsof -i :80 直接列出占用 80 端口的进程名和 PID,比 netstat 更直观。
- ps aux --sort=-%cpu | head 或 ps aux --sort=-%mem | head
不知道哪个进程在吃资源,按 CPU 或内存排一下。测试环境里常见的“服务莫名其妙变慢”,有时候不是服务本身的问题,是同一台机器上另一个进程把 CPU 打满了。
- nc -zv <端口>
ss 和 lsof 只能看本机。要从一台机器测另一台机器的端口通不通,nc -zv 最直接。-z 只测连通,-v 输出详细结果。比 telnet 干净,而且不会在服务端留下半开连接。
第三组:日志,90% 的问题在这里(5 条)
服务状态正常、端口也在听,但结果就是不对。这时候看日志。
- tail -f <日志文件>
实时盯日志。测试提 Bug 的时候,让开发在后台 tail -f,你复现一次,他直接看到报错,比事后翻日志快一个数量级。
- grep -i -n "error|exception|timeout" <日志文件>
日志太长,先筛关键字。-i 忽略大小写,-n 带行号。注意用 | 做“或”匹配,比一条一条 grep 省时间。
- awk '/开始时间/,/结束时间/' <日志文件>
只在某个时间窗口里看日志。测试环境里经常要“复现那一刻的现场”,awk 的范围匹配比 sed 更顺手。
- less +F <日志文件>
less 的 +F 模式跟 tail -f 类似,但可以随时按 Ctrl+C 回到浏览模式,往回翻、搜索关键字,再按 Shift+F 继续跟。排查需要“一边跟一边回看”的场景,比 tail -f 灵活。
- journalctl -f
系统级日志的实时流。服务日志在 /var/log 里,但内核 OOM、systemd 层面的启动失败、依赖服务的报错,会出现在 journalctl 里。
第四组:资源,排查“变慢”(4 条)
不报错,但就是慢。先看资源。
- uptime
一行看负载。三个数字分别是 1 分钟、5 分钟、15 分钟的平均负载。关键不是绝对值,是趋势:1 分钟远高于 15 分钟,说明正在恶化;反过来说明正在恢复。
- top -c
top 不用多说,但 -c 会显示完整的命令行,而不只是进程名。测试环境里同一个 Java 服务可能起了多个实例,-c 帮你区分是哪一个。
- free -h
内存和 swap。重点看 available,不是 free。free 低但 available 高,说明缓存占着但可回收,不是真缺内存。swap 被大量使用,才是性能杀手。
- df -h
磁盘满了,所有写入型接口都会出问题,但报错不一定指向磁盘。测试环境里日志文件、Docker 镜像、临时文件把盘吃满的情况,比想象中常见。
第五组:接口和数据库,排查“数据不对”(3 条)
功能“看起来能用”,但结果不对。这一层已经不是环境问题了,但测试人天天遇到。
- curl -v
-v 输出完整的请求头、响应头、握手过程。排查 403、302、CORS 问题,先看 -v 的输出,比在代码里加日志快。如果只想看响应码,用 curl -s -o /dev/null -w "%{http_code}" 。
- mysql -h -u -p -e ""
测试环境验证数据,经常要直接查库。-e 直接执行一条 SQL 并退出,不用进交互式终端。配合 \G 结尾,输出按行展开,字段多的时候比表格好读。
- docker logs --tail 100 -f <容器名>
测试环境容器化之后,服务日志在容器里,不在宿主机的 /var/log。docker logs 拉的是容器的 stdout/stderr,-f 跟 tail -f 一样实时跟。如果容器反复重启,先看 docker ps -a 的 STATUS 列,再 docker logs 看上一次退出的原因。
排查顺序比命令本身更重要
这 20 条命令,不需要按 1 到 20 的顺序敲。但排查的逻辑有一条线:
先确认“完全不可用”还是“变慢” → 再看服务活没活 → 端口通不通 → 日志有没有异常 → 资源是不是被打满 → 最后才看接口和数据。
环境问题最怕的不是不会敲命令,是在错误的层上反复敲正确的命令。页面 502,先 curl 计时,发现 time_connect 正常、total 很高,说明网络没问题,直接去服务层看 systemctl 和 journalctl,不用先 ping。
顺序对了,20 条命令能解决的问题,比 200 条命令乱敲要多得多。
本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。