← 全部笔记

11 系统管理速查 · 出问题时去哪里看

网络与资源排查:
从症状找到下一条证据

服务要有能到达的入口,进程要有够用的资源。每次只验证一层,你就能把“用不了”缩小成一个具体问题。

约 15 分钟 · 截至 2026-11-06,Ubuntu 26.04 LTS · Ubuntu 环境未实测;输出来自 Debian 13 实测

你的电脑发出 HTTP 请求 运行服务的环境 请求到达 8080 交给 服务进程在监听地址等待连接 内存与 CPU运行时存放数据、执行计算 占用 磁盘 · 保存文件 写入 访问失败:查入口与路径写入失败或变慢:查资源 你的电脑 请求到达 服务的环境 8080 交给 服务进程 · 等待连接 占用 写入 内存与 CPU存放数据、计算 磁盘文件
  • 网络入口地址与端口
  • 磁盘持久保存的文件
  • 运行资源内存与 CPU
图 1 先确定问题发生在请求路径,还是进程依赖的资源上,再选择观察工具;8080 为示意端口。

学完你能

症状一 · 访问不了服务

先在服务所在环境里验证入口

先到运行服务的机器或容器里检查,再从外面访问。localhost 指当前网络环境自身,通常解析到 IPv4 的 127.0.0.1 或 IPv6 的 ::1。你在自己电脑上访问 localhost,不会访问到云服务器。

沿用网络基础的地址与端口模型:监听 127.0.0.1只接受这个环境内部的回环连接;监听 0.0.0.0表示绑定本环境的全部 IPv4 本地地址。后者扩大了接收范围,是否能从远处到达还取决于网络路径与访问规则。[1]

绑定 127.0.0.1:回环入口

服务所在环境 内部客户端 连接 127.0.0.1:8080 外部无匹配入口

绑定 0.0.0.0:全部 IPv4 地址

服务所在环境 外部 IP 交给服务 0.0.0.0:8080 前提:路径可达,防火墙与安全组放行
图 2 绑定地址规定服务接受哪些本地地址上的连接;客户端应访问服务的真实 IP 或域名,别把 0.0.0.0 当成远程目标。

容器里的应用只监听 127.0.0.1:80,宿主机已经发布 -p 8080:80。外部请求转发到容器 IP 的 80,应用会收到吗?

不会。发布规则把请求送到容器 IP 的 80,并不更改应用绑定的地址。应用要接收这条路径的请求,应监听容器 IP 或容器内的 0.0.0.0:80。再按需要限制宿主机发布地址;例如 -p 127.0.0.1:8080:80 把宿主机入口限在回环地址。参见容器与外界:端口映射。[2]

  1. 查谁在监听

    ss -tlnp

    在服务所在环境运行。找 Local Address:Port 和 Process:-t 看 TCP,-l 看监听,-n 显示数字,-p 显示进程。没找到目标端口,就回到服务状态与日志;进程信息为空可能是权限不够。[3]

  2. 本环境里发一个请求

    curl --noproxy '*' --max-time 3 -v http://127.0.0.1:8080/

    例中应用监听回环或全部 IPv4 地址;若只绑定某个网卡 IP,就测试那个 IP。--noproxy '*' 绕过代理,--max-time 3 限时,-v 展示连接过程。收到 HTTP 404/500 说明已收到 HTTP 响应,继续查路径或应用日志;拒绝连接与超时的原因要结合监听、地址和过滤规则判断。[4]

  3. 本地通,再测外部路径

    ip a
    ping -c 2 服务器IP

    ip a 在服务环境里看网络接口及 IP;云主机的公网 IP 可能经云平台映射,不直接出现在网卡上。ping 从客户端发送 ICMP 控制报文,测试对方能否回应;成功不等于 TCP 端口可用,失败也可能只是 ICMP 被过滤。再从客户端用 curl 测真实 IP,核对端口映射、防火墙和云安全组。替换“服务器IP”为实际地址。[5]

下面是 Debian 13 普通用户对自建本地 HTTP 服务的实测摘录,保留原始字段与 PID;PID 是这次运行的进程编号。你的值会不同。上面带 -v 的组合及外部路径测试在 Ubuntu 上未实测;这里只展示实际执行的命令。

ss -tlnp 'sport = :8080'
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 5 127.0.0.1:8080 0.0.0.0:* users:(("python3",pid=48321,fd=3))
curl --noproxy '*' --max-time 3 -sS http://127.0.0.1:8080/
hello from local service

只读 Local Address:Port 才能判断监听范围。右侧 Peer Address:Port 的 0.0.0.0:* 表示监听时尚无固定对端,不能用它判断服务是否对外监听。

上面的本机 curl 成功,另一台电脑访问失败。哪一项最直接解释了现有证据?

服务绑定在哪个地址,要看 Local 一栏;Peer 是连接的另一端。

回环请求没有经过云安全组,不能据此判断外部路径。

127.0.0.1:8080 是直接证据。先按访问需求调整应用监听范围,再从客户端复测;仍失败才继续定位外部路径。扩大监听范围并不会自动放行防火墙。

深入一点:IPv6 与 Docker 的额外边界

::1 是 IPv6 回环地址,[::]:8080 表示 IPv6 通配监听。它是否同时接受 IPv4 取决于套接字设置,不能只凭一行认定。默认桥接容器有独立网络环境;在宿主机运行 ss 不能代替在容器内检查,而且 Docker 的发布规则可由内核转发实现,宿主机 ss 未必列出对应的用户进程监听。结合 docker port 容器名 查看发布规则,再在两侧测试。[2]

症状二 · 磁盘满了

先找满的文件系统,再找大的目录

磁盘保存文件;文件系统负责组织它们。df 看整个文件系统还剩多少空间,du 沿目录统计文件占用。先用失败路径定位文件系统,再逐层缩小目录范围,才能决定处理什么。[6]

df:/work 所在的文件系统 Used 554GAvail 316G du:只统计选中的目录 目录里的文件 ≠ 整个文件系统的账本
图 3 df 定位空间池,du 定位目录占用。条形按实测容量近似绘制;末段灰色为总量减 Used 与 Avail 的差额,二者不保证加起来等于总量。
  1. 定位失败路径所在的存储

    df -h .

    在写入失败的目录运行,或把 . 换成已有的目标目录。看 Avail(可用)、Use%(使用比例)和 Mounted on(挂载点)。接近或达到满额才沿这块存储继续查;-h 让容量便于阅读。

  2. 逐层缩小占用范围

    du -h --max-depth=1 .
    du -ah ./cache

    先看一级子目录,再进入大的那一个;第二条以实测样本里的 cache 目录为例,-a 连文件也列出。先限制在相关目录,避免上来扫描整台机器。遇到权限错误,统计就可能不完整。

  3. 核对归属,再释放空间

    确认文件用途 → 用所属工具清理 → 重跑 df

    区分日志、缓存、构建产物和业务数据;按程序的清理或保留策略处理。修改、删除文件会改变环境,建议在虚拟机或容器里试。Docker 数据要结合数据卷与可写层判断归属。

df -h .
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p2 915G 554G 316G 64% /work

这段记录里的文件系统没有满。若写入仍失败,继续检查实际失败路径、权限、配额或容器可写层,而不是直接删除文件。配额是分给用户或环境的容量上限,可以比整个文件系统更小。

du -h --max-depth=1 .
1.1M ./source
2.1M ./logs
8.1M ./cache
12M .
du -ah ./cache
8.0M ./cache/sample.bin
8.1M ./cache

按“整体空间”与“目录占用”分类,帮下一位排查者选对观察层次。

  • 判断 /work 所在文件系统还有多少 Avail
  • 找项目里哪个子目录占空间最多
  • 清理后确认文件系统可用空间是否增加
  • 查看 cache 里面各个文件的占用
df:整体空间
du:目录占用

df 与 du 回答不同问题。上面样本应先深入 cache,但“占用最大”并不等于“可以删除”;决定清理前还要知道文件用途。

深入一点:有剩余容量为什么还可能报空间不足?

inode 是文件系统记录文件元信息的名额,大量小文件可能先耗尽名额。df -i . 查看 inode 的使用情况(本机实测 IUse% 为 7%,并未耗尽)。已删除但仍被进程打开的文件,也可能继续占空间;因此 df 与 du 不必一致。还要考虑配额、挂载范围和权限,别把两者的差额直接当成可删文件。[7]

症状三 · 机器很卡

先分清内存压力与 CPU 忙碌

先看整机,再找进程。内存的 free 低不一定代表紧张,因为 Linux 会用内存缓存文件;available 估算无需交换就可供新应用使用的内存,更适合作为第一眼线索。它已经考虑可回收缓存,不能再把全部 buff/cache 加上去。[8]

内存:放数据 未使用的 free缓存中可回收的部分 内核估算 available:可供新应用使用 CPU:做计算内存够用时也可能持续忙碌
图 4 available 是考虑缓存可回收程度后的估算;内存是否够用与 CPU 是否忙碌要分别观察。示意图不按容量绘制。
  1. 看整体内存余量

    free -h

    连续观察 Mem 行的 available。持续很低并伴随响应变慢时,再查进程及交换活动;Swap 已用量高只说明有页留在交换空间,单张快照不能证明正在频繁交换。

  2. 看是谁持续占用资源

    htop

    这是动态进程查看器。按 F6 选择 CPU% 或 MEM% 排序,观察多次刷新;RES 是驻留物理内存。先记录 PID、USER 和 Command,再判断是不是预期任务。CPU% 接近 100% 通常相当于用满一个逻辑 CPU,多线程进程可超过 100%;按 q 退出。[9]

  3. 让资源线索与现象对上

    available 低 → 查内存
    CPU 持续高 → 查计算任务
    都不高 → 回到日志与存储

    忙碌可能是正常编译。若内存和 CPU 都宽裕,就继续看日志、磁盘或外部依赖;“机器很卡”本身不能证明内存满了。容器还要看自身的资源上限,宿主机有余量不等于当前容器能继续分配。

工具准备

htop 在精简环境中可能未安装。Ubuntu 中可用 sudo apt install htop 安装;安装会改动系统,建议在虚拟机或容器里试。此安装命令及 Ubuntu 上的 htop 交互未实测。

free -h
total used free shared buff/cache available
Mem: 30Gi 11Gi 4.0Gi 2.6Gi 18Gi 19Gi
Swap: 31Gi 6.5Gi 25Gi

根据这张真实快照,给新应用估算内存余量时,第一眼应看哪列?

列名是 ,此时约有 Gi。

available 约 19 Gi,明显多于 free 的 4.0 Gi,所以这张快照没有显示整机可用内存接近耗尽。仍需按时间观察;在容器里还要结合 cgroup(资源分组)的限额,参见容器隔离与资源边界。

需要干预时

确认归属后,先请求进程正常退出

kill 给进程发送信号,即内核传递的控制通知。默认的 TERM 请求结束,程序可以处理它、保存状态再退出。先用 ps 或 htop 核对 PID、用户和命令;ps 的 STAT 列显示进程状态。对 systemd 管理的服务,优先回到systemctl 停止服务,单独结束进程可能被服务管理器重新拉起。[10]

ps -o pid,user,stat,comm -p 进程号
kill -TERM 进程号
# 等待后重新核对进程状态;仅在确有必要时,对确认过的同一目标发送 KILL
kill -KILL 进程号

这些命令会改变进程状态,建议在虚拟机或容器里试,并只操作自己的练习进程。本机已对自建的 sleep 进程实测 ps 与 TERM;上面是未实测的 Ubuntu 模板,不要复制旧记录里的 PID。KILL 不能被进程捕获,不给它清理机会;处于某些内核等待状态的进程也未必马上消失。

你在 htop 看到一个 CPU 占用很高的进程。用两句话说明:为什么还不能直接发送 KILL?你会先确认什么?

高占用可能是正常工作,应先确认用户、命令、任务用途与持续时间。确定需要停止后,优先使用应用或服务的停止方式,或先发 TERM,等待并复查;必要时才考虑 KILL。

  • 确认进程身份和任务用途,而不是只看占用排名。
  • 说明 TERM 留出退出处理机会,KILL 不给清理机会。

带着证据继续

下一步操作应由上一条证据决定

复用上面的实测证据:/work 的 Avail 为 316G;内存 available 为 19Gi;本机 curl 已成功,但服务只监听 127.0.0.1:8080。目标是让另一台机器直接访问服务,下一步应优先查什么?

这条 df 输出没有显示空间耗尽,清理磁盘无法补出外部监听入口。

这张内存快照也没有显示余量接近耗尽,停止进程与访问失败的证据不对应。

本机成功说明应用在该回环入口有响应;当前绑定范围直接限制了外部访问。先处理这一条已知边界,再继续检查网络路径。把运行位置、失败地址、监听行、curl 结果和资源快照交给 AI 协作者,就能一起沿证据排查。

来源与实测记录可供逐项核对

文档核对日期:2026-11-06,目标系统 Ubuntu 26.04 LTS。实测环境为 Debian 13 amd64 云端容器、普通用户;没有 Docker,无法创建 Ubuntu 实验环境。输出是实测摘录,只做空白排版;不把容器所见的资源快照当成其配额。原始命令及输出包含监听两种地址、curl、ip a、ping、df、du、free 和自建进程的 ps/TERM。Ubuntu 模板、外部路径、真实耗尽场景、安装及 KILL 未实测。

  1. Ubuntu 26.04 ip(7):回环地址、通配绑定与地址/端口。
  2. Docker:Port publishing and mapping:宿主机发布地址、容器目标与内核转发。
  3. Ubuntu 26.04 ss(8):TCP、监听、数字地址和进程信息。
  4. curl 官方手册:verbose、noproxy、max-time 与 HTTP 请求。
  5. Ubuntu 26.04 ip-address(8);ping(8):接口地址与 ICMP 探测。
  6. Ubuntu 26.04 df(1);du(1):文件系统空间、inode 与目录统计范围。
  7. Ubuntu 26.04 unlink(2):仍被打开的文件在最后一个引用关闭前保留。
  8. Ubuntu 26.04 free(1):available、free、buff/cache 与 swap。
  9. Ubuntu 26.04 htop(1):排序、CPU%、MEM%、RES 与退出。
  10. Ubuntu 26.04 kill(1);signal(7):TERM、KILL 与进程信号。