服务挂了、端口被占、日志不知道在哪,这类问题在 SSH 上服务器后最常见。这篇是个人的命令速查手册,每个命令都附上实际场景的用法,不只是参数列表。


端口排查:ss / lsof

ss(socket statistics)是查看网络连接状态的工具,是老版 netstat 的替代品,现代 Linux 发行版默认自带。lsof(list open files)做的事不同——Linux 里一切皆文件,网络连接也算,所以 lsof 可以列出哪个进程打开了哪些文件和网络连接。

查端口占用时两个都能用:ss 速度更快,专注网络;lsof 信息更全(用户、文件描述符),但稍慢。

查看哪个进程在监听某个端口

1
2
3
4
# 查看 8080 端口被哪个进程占用
ss -tlnp | grep 8080
# 或用 lsof(结果更详细)
lsof -i :8080

ss 输出示例:

1
LISTEN  0  128  0.0.0.0:8080  0.0.0.0:*  users:(("java",pid=12345,fd=42))

lsof 输出示例:

1
2
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java 12345 root 42u IPv4 98765 0t0 TCP *:8080 (LISTEN)

两个命令拿到的 PID 一样,lsof 显示的信息更多(用户、文件描述符)。

查看所有监听端口

1
2
ss -tlnp
# -t: TCP,-l: 仅监听状态,-n: 不解析服务名,-p: 显示进程

输出:

1
2
3
4
State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1001))
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=2002))
LISTEN 0 512 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=3003))

查看所有已建立的连接

1
2
3
4
5
# 看有多少客户端连到了 80 端口
ss -tnp | grep :80

# 统计各状态的 TCP 连接数(ESTABLISHED/TIME_WAIT 等)
ss -tn | awk '{print $1}' | sort | uniq -c | sort -rn

netstat(老系统备用)

部分旧服务器没有 ss,用 netstat

1
2
netstat -tlnp         # 查监听端口(需要 net-tools 包)
netstat -anp | grep 8080

进程排查:ps / top

ps(process status)拍一张进程快照,输出当前时刻所有进程的状态,适合搜索特定进程、接管道做过滤。top 是实时监控,每隔几秒刷新一次,适合看某个进程是否在持续吃 CPU 或内存,或者整体资源占用是否异常。

两者互补:想找”java 进程 PID 是多少”用 ps;想看”谁在疯狂吃 CPU”用 top

找某个服务的进程

1
2
3
4
5
6
7
# 找 java 进程(-a: 所有用户,-u: 显示用户,-x: 包含无终端进程)
ps aux | grep java

# 只看进程名精确匹配(不显示 grep 自身)
ps aux | grep '[j]ava'
# 或用 pgrep
pgrep -l java

ps aux 输出列含义:

1
2
USER    PID   %CPU  %MEM     VSZ    RSS TTY  STAT START   TIME COMMAND
root 12345 15.2 8.4 2150432 342012 ? Sl 09:00 10:23 java -jar app.jar
  • %CPU:CPU 占用
  • %MEM:内存占用比例
  • RSS:实际占用的物理内存(KB)
  • STAT:进程状态(S 睡眠、R 运行、Z 僵尸)

看 CPU 和内存占用最高的进程

1
2
3
4
5
# 按 CPU 降序,取前 10
ps aux --sort=-%cpu | head -11

# 按内存降序,取前 10
ps aux --sort=-%mem | head -11

实时监控:top

1
top

进入 top 后的常用操作:

  • P:按 CPU 排序
  • M:按内存排序
  • k:输入 PID 后 kill 进程
  • q:退出

如果服务器装了 htop,用 htop 体验更好(支持鼠标、彩色显示):

1
htop

服务管理:systemctl

systemd 是现代 Linux 上最主流的服务管理器,负责系统启动时按顺序拉起各个服务,并在运行期间维护它们的状态。systemctl 是操作 systemd 的命令行工具。Ubuntu 16.04+、CentOS 7+、Debian 8+ 都用 systemd,基本覆盖了所有主流服务器发行版。

服务的启停、状态查看、开机自启都通过 systemctl 管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看服务状态(有没有在跑、最近的日志)
systemctl status nginx

# 启动 / 停止 / 重启
systemctl start nginx
systemctl stop nginx
systemctl restart nginx

# 平滑重载配置(不中断连接,nginx 支持)
systemctl reload nginx

# 设置开机自启 / 取消
systemctl enable nginx
systemctl disable nginx

# 查看所有正在运行的服务
systemctl list-units --type=service --state=running

# 查看启动失败的服务
systemctl list-units --type=service --state=failed

systemctl status 输出示例:

1
2
3
4
5
6
7
8
9
10
11
 nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2026-07-04 09:00:00 UTC; 2h 30min ago
Process: 1234 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Main PID: 1235 (nginx)
Tasks: 5 (limit: 4915)
Memory: 12.4M
CPU: 1.234s
CGroup: /system.slice/nginx.service
├─1235 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─1236 nginx: worker process

Active: active (running) 说明服务正常运行;Active: failed 说明启动失败。


日志查看:journalctl / tail / less / grep

journalctl 是 systemd 的日志查看工具,专门读取 systemd 收集的结构化日志,可以按服务名、时间段、日志级别过滤。tail 是通用的文本文件查看命令,用于直接读取磁盘上的日志文件。less 是分页查看器,适合打开大日志文件慢慢翻,不会把终端刷满。grep 不是日志工具,但配合以上三个使用可以快速过滤出包含关键词的行。

两者对应两类日志:journalctl 看 systemd 托管的服务日志(比如 nginx、sshd),tail 看应用自己写到文件的日志(比如 /var/log/app/app.log)。

用 journalctl 查 systemd 服务的日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看 nginx 最近的日志
journalctl -u nginx

# 实时跟踪(类似 tail -f)
journalctl -u nginx -f

# 只看最近 100 行
journalctl -u nginx -n 100

# 查某个时间段的日志
journalctl -u nginx --since "2026-07-04 09:00:00" --until "2026-07-04 10:00:00"

# 只看错误级别
journalctl -u nginx -p err

用 tail 看日志文件

应用自己写的日志文件(不走 systemd)用 tail

1
2
3
4
5
6
7
8
# 实时跟踪日志
tail -f /var/log/app/app.log

# 看最后 200 行
tail -n 200 /var/log/app/app.log

# 跟踪日志并过滤 ERROR
tail -f /var/log/app/app.log | grep ERROR

用 less 分页查看大日志

tail 是实时跟踪,less 是”打开文件慢慢翻”。日志文件几十 MB 时直接 cat 会把终端刷满,用 less 可以分页浏览,还能在文件里搜索。

1
less /var/log/app/app.log

进入 less 后的常用操作:

  • G:跳到文件末尾(查最新日志)
  • g:跳到文件开头
  • /keyword:向下搜索关键词,按 n 跳下一个,N 跳上一个
  • q:退出

less +G 直接打开并跳到末尾,省去手动按 G

1
less +G /var/log/app/app.log

用 grep 过滤关键词

grep 本身是文本搜索工具,配合日志使用时可以快速过滤出包含关键词的行,比翻日志文件高效得多。

在日志里搜关键词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 搜包含 "Connection refused" 的行
grep "Connection refused" /var/log/app/app.log

# 忽略大小写
grep -i "error" /var/log/app/app.log

# 显示匹配行后面 3 行(看报错之后发生了什么)
grep -A 3 "panic" /var/log/app/app.log

# 显示匹配行前面 3 行(看报错之前发生了什么)
grep -B 3 "panic" /var/log/app/app.log

# 显示匹配行前后各 3 行(看完整上下文)
grep -C 3 "panic" /var/log/app/app.log

# 统计 ERROR 出现次数
grep -c "ERROR" /var/log/app/app.log

网络连通性:ping / curl / dig

这三个命令分别在不同层面测网络:ping 测 IP 层连通,确认能不能到达对方机器;curl 测 HTTP/HTTPS 层,确认接口能否正常响应;dig 测 DNS 解析,确认域名能不能解析到正确 IP。

排查”外部访问不通”时,通常按这个顺序检查:先 ping 确认网络可达,再 dig 确认 DNS 正确,再 curl 确认服务本身没问题。

ping:测服务器是否可达

1
2
3
4
5
6
7
8
# 基本测试
ping google.com

# 只发 4 个包
ping -c 4 google.com

# 测内网 IP
ping 192.168.1.10

ping 通说明网络层(IP)可达,但 ping 通不代表服务正常——服务可能没起来,或端口没开。

curl:测 HTTP 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 测接口是否返回正常
curl http://localhost:8080/health

# 显示响应头(看状态码、Content-Type)
curl -I http://localhost:8080/health

# 显示完整请求和响应(调试用)
curl -v http://localhost:8080/api/user

# 测 POST 接口
curl -X POST http://localhost:8080/api/login \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"123"}'

# 设置超时(5 秒没响应就报错)
curl --max-time 5 http://localhost:8080/health

# 跟随 301/302 重定向
curl -L http://example.com

dig / nslookup:测 DNS 解析

1
2
3
4
5
6
7
8
9
10
# 查域名解析到哪个 IP
dig example.com
dig example.com A # 只查 A 记录
dig example.com CNAME # 查 CNAME

# 用指定 DNS 服务器查(绕过本地缓存)
dig @8.8.8.8 example.com

# 精简输出
dig +short example.com

nslookup 更简单,适合快速查:

1
2
nslookup example.com
nslookup example.com 8.8.8.8 # 指定 DNS 服务器

traceroute:排查网络路径问题

1
2
3
4
# 查看到目标的路由路径
traceroute google.com

# 在某一跳超时(显示 *)说明那一跳有问题

磁盘和内存:df / du / free

df(disk free)查文件系统级别的磁盘使用,看每个分区还剩多少空间。du(disk usage)查某个目录或文件实际占用了多少空间,适合找出是哪个目录把磁盘撑满了。free 查内存的使用和剩余情况。

服务莫名崩溃,除了看进程和日志,记得用这三个命令确认一下资源有没有被耗尽。

df:查磁盘使用情况

1
2
3
4
5
# 查所有挂载点的磁盘使用(-h: 人类可读)
df -h

# 只看根目录
df -h /

输出:

1
2
3
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1 40G 28G 9.8G 74% /
tmpfs 1.9G 0 1.9G 0% /dev/shm

Use% 接近 100% 说明磁盘快满了,服务可能因为写不了日志而崩。

du:查目录大小

1
2
3
4
5
6
7
8
# 查当前目录下各子目录的大小
du -sh *

# 查指定目录
du -sh /var/log

# 找出最大的目录(排序)
du -sh /var/log/* | sort -rh | head -10

磁盘满了先查 /var/log,日志撑满磁盘是常见原因。

free:查内存使用

1
free -h

输出:

1
2
3
               total        used        free      shared  buff/cache   available
Mem: 15Gi 8.2Gi 2.1Gi 512Mi 5.1Gi 6.7Gi
Swap: 2.0Gi 512Mi 1.5Gi
  • available:实际可用内存(比 free 更准确,包含可回收的 cache;procps-ng 3.3.10+ 才有此列,旧系统可能没有)
  • Swap used 过高说明物理内存不够,系统在用交换分区,服务会变慢

服务访问不通时的完整排查顺序

服务访问不通,按这个顺序查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 1. 确认服务进程是否在跑
ps aux | grep '[a]pp'
# 或
systemctl status myapp

# 2. 确认端口是否在监听
ss -tlnp | grep 8080

# 3. 本机测接口是否正常
curl -v http://localhost:8080/health

# 4. 看服务最近的错误日志
journalctl -u myapp -n 100 -p err
# 或
tail -n 200 /var/log/myapp/app.log | grep -i error

# 5. 检查磁盘和内存是否耗尽
df -h /
free -h

# 6. 如果是域名访问不通,查 DNS
dig +short mydomain.com

# 7. 如果是外部访问不通但本机正常,检查防火墙
# Ubuntu/Debian
ufw status
# CentOS/RHEL
firewall-cmd --list-all

大多数”服务挂了”的情况,前四步就能定位:进程死了 → 重启;端口没监听 → 看启动日志;接口报错 → 看应用日志;磁盘满 → 清日志。