服务器修复

 人参与 | 时间:2026-10-17 07:08:47
```html 服务器修复

服务器修复

凌晨两点十七分,报警短信像闹钟一样准时。器修我摸过手机,服务复屏幕亮得刺眼——API 响应时间突破 12 秒,器修错误率 47%。服务复这不是器修第一次了,但每次心跳都会漏一拍。服务复从床上坐起来的器修时候,脚趾踢到了床角的服务复铁架,疼得我倒吸一口气。器修顾不上那么多,服务复光脚踩在地板上,器修凉意从脚底窜上来,服务复人倒是器修清醒了。

SSH 连上去,服务复top 第一行就告诉我问题在哪。负载 38.2,CPU 使用率 96%,内存只剩 200MB 可用。但这台机器是 16 核 64G 的配置,跑一个日均请求量不过百万的 API 服务,正常负载应该在 2 以下。哪里不对。

先看进程列表。一个叫 backup_worker 的进程吃了 12 个核,内存占用 18G。这东西平时只是每天凌晨四点跑一次增量备份,十分钟就结束。现在它像疯了一样在跑。我翻了一下它的日志文件,最后一行写着:Scanning /mnt/data/archive/... 3,847,291 files found。三百万个文件?这个目录以前只有不到十万个文件。有人往里面灌了东西。

我立刻 kill -9 掉那个进程。负载从 38 掉到 6,但还在涨。因为另一个问题浮出来了——磁盘 I/O 等待时间 89%。iostat -x 1 显示 sdb 盘的 %util 一直是 100%。这盘是数据盘,挂载在 /mnt/data。进去一看,archive 目录下全是小文件,每个 2KB 左右,文件名是哈希值。我数了一下,接近三百万个。这不是正常业务数据。

脑子转得飞快。最近没有部署新版本,没有改过备份策略。那这些文件哪来的?查了一下 /var/log/nginx/access.log,发现过去六个小时里,有一个 IP 一直在调一个废弃的上传接口,每次传一个 2KB 的加密块,文件名是随机哈希。接口没做频率限制,也没做文件类型校验。攻击者用这个漏洞往磁盘里灌垃圾,把备份进程拖死,顺带把磁盘 I/O 打满,导致所有依赖数据库的请求全部超时。

找到根因就好办了。先停掉 Nginx 里那个废弃接口的 location 块,nginx -s reload。然后写个脚本批量删除那些小文件——不能用 rm -rf,三百万个文件会把 inode 耗尽。用 find /mnt/data/archive -type f -name "*.blk" -delete,加上 -print 输出进度,跑了将近四十分钟。期间我泡了碗泡面,红烧牛肉味的,吃完发现叉子还插在碗里没扔。

文件删干净之后,磁盘 I/O 降下来了。iostat 显示 %util 从 100% 掉到 3%。负载回到 0.8。API 响应时间恢复到 120ms。但事情没完——那个废弃接口为什么还能访问?翻了一下代码仓库,三个月前重构的时候,路由配置里留了一行注释掉的 legacy_upload,但 Nginx 的配置文件里对应的 location 没删。开发以为注释掉代码就安全了,运维以为开发会清理 Nginx。两边都没错,但两边都没做。


修复完是凌晨四点零九分。我盯着监控面板看了五分钟,曲线平稳得像什么都没发生过。但我知道,这种问题不是第一次,也不会是最后一次。服务器不会无缘无故坏掉,每一次崩溃背后都有一个被忽略的细节——一个没删的配置、一行没校验的代码、一个没设上限的接口。修服务器这件事,说到底是在修人的疏忽。

关掉终端之前,我加了一条告警规则:archive 目录文件数超过 50 万就发短信。然后去洗了把脸,镜子里的人眼睛红得像兔子。躺回床上的时候,脚趾还在隐隐作痛。

``` 顶: 88踩: 5144