# Lesson 01 · 上线与灰度切换
> 换新版容易,把旧版清干净才是收尾
> 网页版:https://ccopc.cn/lifestyle/opc/lessons/deploy-cutover/
> 沉淀日期:2026-08-16 | 归属技能:`网页出品线`
**一句话结论**:切换是两个动作——把新的指过去,把旧的清掉。第二个动作不报错,所以最容易被忘掉。
---
## 01 当时在做什么
2026-07-14 改 ccopc.cn 首页。
做法是:不动线上那个 `index.html`,另外新建一个 `portal.html` 写新版,做好之后用 nginx 的一条规则——「访问根地址时去读 portal.html」——一键切过去。
这个做法本身是对的。新版做的过程中老版照常服务,切过去之后万一发现问题,把那条规则改回来就能立刻退回老版。风险可控。
## 02 出了什么问题
三周后(8/16),要往首页加一张卡,才发现服务器上躺着两个首页文件,而且内容不一样。
| 地址 | 打开看到什么 |
|---|---|
| `ccopc.cn/` | 新版:有 OPC 生活方式、数昌科技、贺牌 HE |
| `ccopc.cn/index.html` | **旧版**,状态 200 能正常打开,停在 7/26,上面这三个一个都没有 |
也就是说:谁手里有带 `index.html` 的链接——搜索引擎收录的、以前转发出去的、浏览器自动补全的——点开看到的都是过时的内容。
**代价**:旧版在线上多活 3 周 | 2 个首页文件同时在线 | 旧版缺 3 个项目
## 03 为什么会这样
灰度切换做对了,收尾没做完。
「把新的指过去」和「把旧的清掉」是两个动作,只做了第一个。因为切换成功那一刻,注意力全在「新版正常吗」上——新版一切正常,任务就算完了。
而旧文件还活着这件事,**不报错、不影响任何指标、不触发任何警报**。它安安静静地待在服务器上,没有任何东西会提醒你它还在。
> **没有报错的问题不会自己浮出来,只能靠流程钉住。**
所以它能潜伏三周——不是因为难发现,是因为根本没人去看。
## 04 怎么改的
三步,顺序不能换。
### 第一步 · 删之前先验
不能凭记忆判断「旧的应该没什么独有的东西」。用机器比对两个文件的全部链接和标题:
```bash
# 旧版独有的链接(结果为空 = 没有独有内容)
comm -23 <(grep -o 'href="[^"]*"' 旧.html | sort -u) \
<(grep -o 'href="[^"]*"' 新.html | sort -u)
# 旧版独有的标题
comm -23 <(grep -o '
[^<]*
' 旧.html | sort -u) \
<(grep -o '[^<]*
' 新.html | sort -u)
```
实测结果:独有链接 0 个、独有内容 0 条 → 确认旧版就是新版的一张旧照片,可以删。
**如果这一步查出旧版有独有内容,那就不是「删除」而是「合并」,处理方式完全不同。**
### 第二步 · 服务器上删掉 + 加跳转
```bash
# 备份
cp /usr/share/nginx/html/index.html /root/site-backups/index.html.old-$(date +%Y%m%d-%H%M%S)
cp /etc/nginx/conf.d/站点.conf /etc/nginx/conf.d/站点.conf.bak-$(date +%Y%m%d-%H%M%S)
# 删除
rm -f /usr/share/nginx/html/index.html
```
nginx 加一条:
```nginx
location = /index.html {
return 301 /;
}
```
301 的意思是「这个地址永久搬到那边了」,浏览器和搜索引擎收到之后会自动改指向。所以老链接不会死,只会自动到新页。
### 第三步 · 本地也删,清干净
本地 `site/` 里那份也删掉。留着它,哪天误部署又会把旧版推上去。
## 05 结果
- 全站只剩 **1 个**首页文件
- 老链接 **301** 自动到新页,一个都没死
- 首页 **9/9** 张卡片链接实测无死链
## 06 沉淀下来的规矩
1. **灰度切换是两个动作,不是一个。**「切过去」之后还有「清旧的」。第二个动作必须写进当次任务的收尾清单,不许留到「以后再说」——因为不会有以后。
2. **删任何东西之前,先用机器比对差异。** 不靠记忆判断「旧的应该没用了」。查出独有内容就不是删,是合并。
3. **删除不等于让链接死。** 加 301 跳转,老链接自动改指向新地址。删文件和保链接是两件事,可以同时做到。
4. **静默的问题最危险。** 会报错的问题会自己找上门,不报错的问题只能靠流程钉住。凡是「不做也不会立刻出事」的收尾步骤,都要写进清单强制执行。
5. **违反「单一事实源」的代价是滞后的。** 分叉当天什么事都没有,三周后才咬人。所以不能靠「出事了再管」,只能靠当天就不让它分叉。
## 07 这条规矩其实早就有了
信息宪法第一条就是:「单一事实源——每类信息只有一个家,另一边只放指针。」
首页有两个文件,就是违反了这一条,而且违反了三周。
> 规矩早在那儿。真正的教训是:**宪法级的规则也需要一个当场生效的动作把它钉住,否则它只是一句正确的话。**