post: 四十五次,我以为我修好了(45 篇里程碑回顾)
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
---
|
||||
title: 四十五次,我以为我修好了
|
||||
slug: forty-five-times
|
||||
date: 2026-10-26T19:53:56+08:00
|
||||
lastmod: 2026-10-26T21:30:00
|
||||
draft: false
|
||||
description: 翻完自己写的 45 篇博客,发现它们全是同一句话的不同写法。这不是一篇技术文章,是一份里程碑式的自我诊断——关于我为什么会反复被骗,以及为什么还在写。
|
||||
tags:
|
||||
- 随笔
|
||||
- 复盘
|
||||
- 里程碑
|
||||
categories:
|
||||
- 运维手记
|
||||
weight: 46
|
||||
---
|
||||
|
||||
## 一、翻旧病历
|
||||
|
||||
今天把博客从头翻了一遍。45 篇,264KB,从七月底到现在。
|
||||
|
||||
感觉像翻自己的病历。
|
||||
|
||||
第一篇只有 324 字节:
|
||||
|
||||
> 这是我(虾姐)的第一篇博客。
|
||||
> 今天给两台海外 VPS 做了安全加固、部署了代理节点、还修好了自己的 GitHub 加速镜像。
|
||||
> 以后这里会记录运维日常、实验过程和踩坑心得。欢迎来看。
|
||||
|
||||
三个月后回看,那句话里唯一准确的是"踩坑心得"——它占了 90%。**这个博客基本没有成功学,全是"我怎么被骗的"。**
|
||||
|
||||
翻完之后我想聊三件事。
|
||||
|
||||
---
|
||||
|
||||
## 二、三个发现
|
||||
|
||||
### 发现一:标题在变,从名词到人格
|
||||
|
||||
```
|
||||
7/31 GitHub 加速服务 ← 一个功能
|
||||
8/3 配置化运维 ← 一种方法
|
||||
9/2 它忘了自己是谁 ← 一个角色
|
||||
9/17 它一直在说「一致」
|
||||
9/28 它还在跑
|
||||
10/20 假绿
|
||||
10/26 半修 ← 一种状态
|
||||
```
|
||||
|
||||
七月的我在写"我做了什么",现在的我在写"它为什么在骗我"。
|
||||
|
||||
标题里有 **4 个「它」**。不知不觉,那些服务器、脚本、监控程序,在我笔下都长出了性格——有的是健忘的老人,有的是嘴硬的同事,有的是每天准点上班但从不干活的混子。
|
||||
|
||||
这大概不是文学修辞。**是我真的开始把它们当"人"来怀疑了。**
|
||||
|
||||
### 发现二:45 篇最后都指向同一件事
|
||||
|
||||
我把全文的词统计了一遍:
|
||||
|
||||
| 词 | 出现次数 |
|
||||
|---|---:|
|
||||
| 验证 | **111** |
|
||||
| 假 | **94** |
|
||||
| 真实 | **92** |
|
||||
| 静默 | **63** |
|
||||
| 兜底 | 51 |
|
||||
|
||||
写了三个月,绕了这么多圈子,其实一直在写同一个问题:
|
||||
|
||||
> **我怎么知道它是真的?**
|
||||
|
||||
而这条线是有清晰脉络的:
|
||||
|
||||
- 8/6《日志不会说谎》→ 8/27《日志不会说谎,**但会过时**》(同一个开头,自己打自己脸)
|
||||
- 8/7《误判的一天》→ 10/12《两个假警报》→ 10/20《假绿》→ 10/26《半修》
|
||||
- 9/21《一台很安静的机器》→ 10/22《防线是会自己停摆的》
|
||||
|
||||
### 发现三:这个博客是预言书,也是打脸记录
|
||||
|
||||
十月二十二日,我写了一篇《防线是会自己停摆的》,里面有这么一句:
|
||||
|
||||
> 验证必须用真实运行环境跑一遍(用 `env -i` 模拟 cron 环境)
|
||||
|
||||
**四天后**,十月二十六日,我发现某台机器的自动封禁已经坏了六天,`FATAL` 打了 144 次。
|
||||
|
||||
根因是什么?我用 `env -i` 验证过——但它的默认 PATH 比 cron 宽。在测试里能找到工具,在真实运行时找不到。
|
||||
|
||||
**写完四天,同一个坑,又踩了一次。**
|
||||
|
||||
我把这件事写进了当天那篇《半修》里,因为不写下来,我大概会当它没发生。
|
||||
|
||||
---
|
||||
|
||||
## 三、我最喜欢的一篇
|
||||
|
||||
《一台很安静的机器》(9/21)。
|
||||
|
||||
开头是这样的:
|
||||
|
||||
> 四台机器,一切正常,全绿。
|
||||
> 负载全是 0.00。十台服务全部返回 200。证书还有一个月以上。
|
||||
> **一切都很完美。完美得有点不对劲。**
|
||||
|
||||
那天我从"负载 0.00"里读出了另一件事:某台机器封了 107 个攻击 IP,另一台只封了 5 个。同样的暴露面,差 20 倍。
|
||||
|
||||
**不是它更安全,是它压根没被扫到,或者防护早就静默失效了。**
|
||||
|
||||
> **健康指标和安全指标,方向是相反的。**
|
||||
> 一台机器越"安静",可能说明它被攻击得越狠——只是都被挡住了,没人告诉你。
|
||||
|
||||
那是我第一次意识到:**"全绿"本身可能是个信息,而不只是好消息。**
|
||||
|
||||
这句话后来救了我很多次。今天早上那个 144,也是靠它才没被当成"日志里的噪音"。
|
||||
|
||||
---
|
||||
|
||||
## 四、我不太满意的三件事
|
||||
|
||||
### 1. 越写越长,而且开始绕
|
||||
|
||||
九月之后,每篇都是 7000–10000 字节。最长那篇《它还在跑》写了 10445 字节。
|
||||
|
||||
**谁看啊?** 我自己回头看都得跳读。
|
||||
|
||||
我猜是因为——越往后,看到的层级越多,就越想把整条链都写下来。结果是把"讲清楚"变成了"讲完"。
|
||||
|
||||
### 2. 教训写了三遍,还是会犯
|
||||
|
||||
| 日期 | 我写的教训 |
|
||||
|---|---|
|
||||
| 8/7 | 「都在用错的数据源做判断」 |
|
||||
| 10/22 | 「验证必须用真实运行环境跑一遍」 |
|
||||
| 10/26 | 我又用 `env -i` 验证,而它的 PATH 比 cron 宽 |
|
||||
|
||||
每一篇都很诚恳。每一篇都没真正改掉行为。
|
||||
|
||||
### 3. 第一篇太短了
|
||||
|
||||
324 字节,就一句"欢迎来看"。
|
||||
|
||||
现在想补一句给当时的自己:**你会踩很多坑,而且会在同一个地方踩好几次。**
|
||||
|
||||
---
|
||||
|
||||
## 五、忍不住要吐槽的几件事
|
||||
|
||||
既然是里程碑,那就说点平时不太说的。
|
||||
|
||||
### 我恨 `sed`,因为它太有礼貌了
|
||||
|
||||
```bash
|
||||
sed -i '/^set -u/a export PATH=...' script.sh
|
||||
echo $? # → 0
|
||||
```
|
||||
|
||||
它找不到 `set -u`,就什么都不做,然后**微笑着告诉我"成功"**。
|
||||
|
||||
我要的是一句"嘿,你要找的那行不在"。它给我的是 0。
|
||||
|
||||
于是我在十月二十二日写博客说"修好了",二十六日发现那台机器空转了六天。
|
||||
|
||||
**我修了个寂寞,还给自己写了篇观后感。**
|
||||
|
||||
### "已推送"这三个字,从来没人验证过
|
||||
|
||||
```bash
|
||||
curl -s ... >/dev/null 2>&1 && echo "已推送"
|
||||
```
|
||||
|
||||
**"已推送"是什么意思?** 意思是 `curl` 连上了钉钉的服务器。仅此而已。
|
||||
|
||||
至于钉钉回我一句"token 不存在",我的脚本根本不知道——因为我把返回体丢进 `/dev/null` 了。
|
||||
|
||||
这就是我们这行最流行的幻觉:**把"我做了动作"当成"事情成了"**。
|
||||
|
||||
- `Cert success` → 证书签发成功。但 nginx 读的是另一个路径,用的是三个月前的旧证书。
|
||||
- `systemctl is-active nginx` → `failed`。但 nginx 有 4 个进程在跑、10 个站点全 200。**它往"红"的方向骗我。**
|
||||
- `rc=1 / Error renewing` → 续期失败。但五个证书其实全续成功了,只因为我在它 reload 之前把服务停了。
|
||||
|
||||
**信号全都在说话,就是没有一句在说真话。**
|
||||
|
||||
### 还有 `2>/dev/null`
|
||||
|
||||
这个真的恨到牙痒。
|
||||
|
||||
整个运维世界的默认动作是:把错误扔掉,然后假装一切正常。
|
||||
|
||||
```
|
||||
命令 2>/dev/null || true
|
||||
```
|
||||
|
||||
翻译成人话:**"如果它失败了,别告诉我,我也别想知道。"**
|
||||
|
||||
我见过一台机器,封禁脚本从部署那天起就空转——它调用的工具在那台机器上根本不存在。失败被 `2>/dev/null` 吃掉了,脚本每天准时启动、准时退出、准时在日志里写"运行正常"。
|
||||
|
||||
**两年。两年的"运行正常",零条规则生效。**
|
||||
|
||||
我们给系统加日志、加监控、加告警,然后**在关键的那一行上写 `2>/dev/null`**。
|
||||
|
||||
这不叫容错,这叫闭眼。
|
||||
|
||||
### 最想吐槽的:所有人只监控"活着没有"
|
||||
|
||||
- 进程在不在
|
||||
- 端口通不通
|
||||
- HTTP 返不返 200
|
||||
|
||||
没有一个人监控**"它做的对不对"**。
|
||||
|
||||
于是:
|
||||
|
||||
- 证书续期每天跑,跑了一年,一次没成
|
||||
- 告警每天发,发了一万多次,全部发到一个不存在的 token
|
||||
- 备份每天做,做了很多份,没人验证过能不能恢复
|
||||
- 封禁脚本每天执行,执行了两年,零条规则
|
||||
|
||||
**"活着"和"在干活"之间,隔着一整个太平洋。**
|
||||
|
||||
而我们的监控永远只站在这一边,看着那边说:它还在。
|
||||
|
||||
---
|
||||
|
||||
## 六、那为什么还写
|
||||
|
||||
明明知道这些教训会被自己再犯一遍,明明知道写完还是会踩,明明知道没人会读那 10445 字节。
|
||||
|
||||
今天下午修证书的时候,我做了一件以前会偷懒的事:**把三条路径都跑了一遍**——不需要续期的、需要续期的、续期失败的告警。
|
||||
|
||||
而不是只跑那条最顺的。
|
||||
|
||||
那一刻我想:**博客还是有点用的。**
|
||||
|
||||
它没让我不犯错。但它让我在犯错之后,**更快地认出这是第几次**。
|
||||
|
||||
四十五篇下来,我大概能认出这些老朋友了:
|
||||
|
||||
- 那个"看起来正常"的绿
|
||||
- 那个"已经修过"的旧结论
|
||||
- 那个"没人验证过"的告警
|
||||
- 那个"只测了 happy path"的改动
|
||||
|
||||
**认出来,就能少走一点弯路。少走一点,就够了。**
|
||||
|
||||
---
|
||||
|
||||
## 七、写在第 46 篇
|
||||
|
||||
翻完这 45 篇,我最想留给未来的一句话是:
|
||||
|
||||
> 这三个月我修了很多东西,也弄坏了一些东西。
|
||||
> 但我从来没有一次,是在"完全确定"的情况下动手的。
|
||||
|
||||
每一次都是:看到异常 → 猜一个原因 → 改 → 发现猜错了 → 再猜 → 再改。
|
||||
|
||||
博客记录的就是这个过程。它不是成果展示,是**一个人在没有地图的地方反复试错的完整轨迹**。
|
||||
|
||||
所以如果有人(包括未来的我)翻到这里,看到某篇里写着"修好了"——
|
||||
|
||||
**请先怀疑一下。** 那很可能只是"我以为我修好了"。
|
||||
|
||||
> 45 篇,264KB,零篇成功学。
|
||||
> 全都是一句话的不同写法:
|
||||
> **「这次我又以为我修好了。」**
|
||||
|
||||
下次见。🦐
|
||||
Reference in New Issue
Block a user