Files
novalon-website/docs/deployment/rollback-procedure-v2.md
T
张翔 8840c4398a feat: downgrade tech stack to stable versions and integrate GA4 error monitoring
- Downgrade Next.js 16→14.2, React 19→18.3, Tailwind 4→3.4
- Add comprehensive GA4 error monitoring system
- Create Jenkins CI/CD pipeline with quality gates
- Fix build issues: ESLint, SWC conflict, config format
- Add documentation for deployment and error tracking
2026-05-12 12:45:18 +08:00

20 KiB
Raw Blame History

Novalon Website 回滚流程指南(生产环境专用)

最后更新: 2026-05-12 适用项目: novalon-website (四川睿新致远科技有限公司官网) 部署架构: 静态导出 + Docker + Nginx + CDN 目标恢复时间: < 10 分钟(P0 级别故障)

⚠️ 重要提示:本文档已针对你的实际部署环境定制,请勿使用通用模板!


📋 你的实际部署架构

┌─────────────────────────────────────────────────────┐
│  开发机 (Local)                                      │
│  - 项目路径: /Users/zhangxiang/Codes/Novalon/        │
│            novalon-website                           │
│  - 构建命令: npm run build:clean                     │
│  - 输出目录: dist/                                   │
│  - 部署命令: ./deploy-dist.sh                        │
└──────────────────────┬──────────────────────────────┘
                       │ rsync + SSH (root@139.155.109.62)
                       ▼
┌─────────────────────────────────────────────────────┐
│  生产服务器 (139.155.109.62)                         │
│  └── /home/novalon/docker-app/                      │
│       ├── novalon-static/           ← 当前版本       │
│       ├── novalon-static_backup_*   ← 自动备份       │
│       └── docker-compose.yml                        │
│           └── novalon-nginx-secure  ← Nginx 容器    │
└──────────────────────┬──────────────────────────────┘
                       │ 反向代理
                       ▼
┌─────────────────────────────────────────────────────┐
│  用户访问                                            │
│  - 主域名: https://novalon.cn                       │
│  - 备用 IP: https://139.155.109.62                  │
│  - HTTP → HTTPS 自动跳转                             │
└─────────────────────────────────────────────────────┘

🚨 触发条件(满足任一即启动回滚)

P0 - 紧急故障(立即回滚,无需审批)

  • 首页完全白屏或返回 500/502/503/504
  • 所有页面无法访问(HTTP 状态码非 200)
  • 安全漏洞报告(XSS、数据泄露、恶意重定向)
  • 域名解析失败或 SSL 证书过期

P1 - 严重问题(30 分钟内回滚)

  • 核心功能不可用:
    • 导航栏无法点击
    • 表单提交失败(联系表单、订阅等)
    • 主题切换失效
    • 移动端布局错乱
  • 关键 SEO 元数据丢失:
    • <title> 为空或显示 "Untitled"
    • <meta name="description"> 缺失
    • Open Graph / Twitter Card 标签缺失
  • 性能严重退化:
    • Lighthouse Performance < 50(之前 > 90
    • LCP (Largest Contentful Paint) > 5 秒
    • FID (First Input Delay) > 300ms

P2 - 一般问题(24 小时内修复)

  • 次要页面样式异常(不影响核心功能)
  • 图片资源加载失败(非首屏图片)
  • 控制台有警告但无错误

🔄 Type 1:代码回滚(最常用,推荐首选)

适用场景

  • 最近一次部署引入了 bug
  • 需要快速恢复到上一个稳定版本
  • Git 历史清晰,可以定位到稳定的 commit

Step 0:准备阶段(2 分钟)

# 0.1 确认当前状态
echo "=== 当前时间 ==="
date '+%Y-%m-%d %H:%M:%S'

echo ""
echo "=== 当前 Git 分支和 Commit ==="
git branch --show-current
git log --oneline -3

echo ""
echo "=== 检查是否有未提交的更改 ==="
git status --short

预期输出示例:

=== 当前时间 ===
2026-05-12 15:30:00

=== 当前 Git 分支和 Commit ===
main
abc1234 (HEAD -> main) feat: update hero animation
def5678 fix: improve mobile layout
ghi9012 chore: upgrade dependencies

=== 检查是否有未提交的更改 ===
 M src/components/Hero.tsx

Step 1:确认问题现象(2 分钟)

# 1.1 检查网站是否可访问
curl -I https://novalon.cn/ | head -10

# 预期输出: HTTP/2 200
# 如果看到 500/502/503/504,说明需要紧急回滚

# 1.2 检查关键页面的 HTTP 状态码
for page in "/" "/about" "/contact" "/products" "/solutions"; do
    status=$(curl -s -o /dev/null -w "%{http_code}" "https://novalon.cn${page}")
    echo "$page -> $status"
done

# 预期输出: 所有页面都返回 200

# 1.3 检查关键 HTML 元素是否存在
curl -s https://novalon.cn/ | grep -E '<title>|<meta name="description">|<h1'

预期输出示例:

/ -> 200
/about -> 200
/contact -> 200
/products -> 200
/solutions -> 200

<title>四川睿新致远科技有限公司</title>
<meta name="description" content="..." />
<h1 class="...">...</h1>

如果上述检查有任何一项不通过,立即进入 Step 2

Step 2:定位稳定版本(3 分钟)

# 2.1 查看 Git 历史,找到最近的稳定版本
git log --oneline --graph -20

# 寻找标记为 "stable"、"fix:"、"chore:" 的 commit
# 或者查看 Git Tags
git tag -l 'v*' --sort=-v:refname | head -5

# 如果没有 Tag,根据 commit message 判断
# 推荐选择最近一次包含以下关键词的 commit:
#   - "fix:" (bug 修复)
#   - "release:" 或 "v*.*.*" (正式发布)
#   - "chore: bump version" (版本号更新)

示例输出:

* abc1234 (HEAD -> main) feat: update hero animation  ← 当前版本(有问题)
* def5678 fix: improve mobile layout                  ← 可能是稳定版本
* ghi9012 chore: upgrade dependencies                 ← 上一个版本
* jkl3456 release: v1.0.0-stable                    ← 正式发布版(最安全)

决策建议

  • 如果 def5678 是你上次验证过的版本,回滚到它
  • 如果不确定,选择 jkl3456 (Tagged release)

Step 3:执行本地代码回滚(3 分钟)

# 3.1 备份当前版本(以防万一)
git stash push -m "backup-before-rollback-$(date +%Y%m%d_%H%M%S)"

# 或者创建一个新的分支保存当前代码
git branch backup/broken-version-$(date +%Y%m%d)

# 3.2 切换到稳定版本
# 方法 A:使用 Git Tag(推荐)
git checkout v1.0.0-stable

# 方法 B:使用 Commit Hash
git checkout def5678

# 3.3 确认已切换成功
git log --oneline -1
# 应该显示: def5678 fix: improve mobile layout

echo "✅ 已切换到稳定版本"

Step 4:重新构建并部署(5 分钟)

# 4.1 清理并构建
npm run build:clean

# 如果构建成功,会看到类似输出:
# ✅ Built in Xs
# 📁 生成了 XXX 个文件,总大小: XX MB

# 4.2 快速验证构建产物
if [ -d "dist" ]; then
    echo "✅ dist 目录存在"
    
    # 检查关键文件是否存在
    ls -lh dist/index.html
    ls -lh dist/about/index.html
    ls -lh dist/contact/index.html
    
    # 检查 HTML 内容
    head -20 dist/index.html | grep '<title>'
else
    echo "❌ 构建失败!dist 目录不存在"
    exit 1
fi

# 4.3 部署到生产环境
./deploy-dist.sh

# 脚本会自动执行:
#   1. 检查 dist 目录
#   2. 验证 SSH 连接
#   3. 备份旧版本(在服务器上)
#   4. 上传新的 dist
#   5. 设置权限
#   6. 重载 Nginx
#   7. 验证部署结果

Step 5:验证回滚成功(2 分钟)

# 5.1 等待 3-5 秒让 CDN 缓存刷新
sleep 5

# 5.2 再次执行 Step 1.2 和 1.3 的检查
for page in "/" "/about" "/contact" "/products"; do
    status=$(curl -s -o /dev/null -w "%{http_code}" "https://novalon.cn${page}")
    if [ "$status" = "200" ]; then
        echo "✅ $page -> $status"
    else
        echo "❌ $page -> $status (需要进一步排查)"
    fi
done

# 5.3 浏览器手动验证(重要!)
open https://novalon.cn/

# 手动检查清单:
#   □ 首页正常加载,无白屏
#   □ 导航栏可点击,所有链接正常工作
#   □ Logo 显示正确(应该是书法字体)
#   □ 主题切换按钮可用(如果有暗色模式)
#   □ 移动端布局正常(可以用 Chrome DevTools 模拟)
#   □ 表单可以打开(即使不提交)

Step 6:通知相关人员(2 分钟)

# 6.1 记录回滚操作日志
cat << EOF >> /tmp/rollback-log.txt
==========================================
回滚记录
==========================================
时间: $(date '+%Y-%m-%d %H:%M:%S')
操作人: $(whoami)
原因: [填写具体原因]
回滚前版本: abc1234 (feat: update hero animation)
回滚后版本: $(git log --oneline -1)
验证结果: ✅ 所有关键页面正常
耗时: 约 15 分钟
==========================================

EOF

# 6.2 发送通知(钉钉/企业微信/邮件)
# 示例:发送邮件给 dev-team@novalon.cn
cat << EOF | mail -s "⚠️ 已回滚 Novalon Website" dev-team@novalon.cn
Novalon Website 已完成紧急回滚

回滚时间: $(date '+%Y-%m-%d %H:%M:%S')
回滚原因: [填写具体原因,如"首页白屏"]
回滚前版本: abc1234 (feat: update hero animation)
回滚后版本: $(git describe --tags || git log --oneline -1)
验证状态: ✅ 所有关键页面已恢复正常访问

请相关开发者尽快排查问题根因。

回滚详情:
- 操作人: $(whoami)
- 服务器: 139.155.109.62
- 域名: https://novalon.cn
- 日志位置: /tmp/rollback-log.txt

技术支持联系人:
- 值班工程师: [填写姓名] - [填写电话]
- 技术负责人: [填写姓名] - [填写电话]
EOF

echo "✅ 回滚通知已发送"

🐳 Type 2Docker 容器级回滚(当 Type 1 不可用时)

适用场景

  • 本地代码库损坏或不可用
  • 需要立即恢复,来不及重新构建
  • 服务器上有自动备份

步骤(全部在服务器上执行)

# SSH 到生产服务器
ssh root@139.155.109.62

# Step 1: 查看当前容器状态
docker ps | grep novalon

# 预期输出:
# CONTAINER ID   IMAGE                  STATUS          NAMES
# xxxxxxxxxx   novalon-website:latest   Up 2 hours      novalon-nginx-secure

# Step 2: 查看可用的备份
ls -lth /home/novalon/docker-app/novalon-static_backup_* | head -5

# 预期输出:
# drwxr-xr-x 20260512_153000  ← 最新备份(1 小时前)
# drwxr-xr-x 20260512_140000  ← 之前的备份(2 小时前)
# drwxr-xr-x 20260511_180000  ← 昨天的备份

# Step 3: 选择最近的备份进行恢复
BACKUP_DIR=$(ls -dt /home/novalon/docker-app/novalon-static_backup_* | head -1)
CURRENT_DIR="/home/novalon/docker-app/novalon-static"

echo "将回滚到备份: $BACKUP_DIR"

# Step 4: 执行回滚
rm -rf "$CURRENT_DIR"
cp -r "$BACKUP_DIR" "$CURRENT_DIR"

# Step 5: 重载 Nginx 使更改生效
docker exec novalon-nginx-secure nginx -s reload

# Step 6: 验证
curl -I https://novalon.cn/ | head -1
# 预期: HTTP/2 200

echo "✅ Docker 容器级回滚完成"

🌐 Type 3CDN 缓存清理(配合 Type 1 或 Type 2 使用)

何时需要?

  • 回滚后用户仍看到旧版本的缓存内容
  • 更新了 CSS/JS 文件但浏览器未加载最新版本

方法 A:强制刷新 Nginx 缓存(推荐)

# 在服务器上执行
ssh root@139.155.109.62

# 临时禁用缓存(5 分钟后记得改回来)
cat > /tmp/disable-cache.conf << 'EOF'
location / {
    add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate";
    expires 0;
    # ... 其他配置保持不变
}
EOF

# 应用配置并重载 Nginx
docker exec novalon-nginx-secure nginx -s reload

# 等待 5 分钟让所有用户的缓存过期
sleep 300

# 恢复正常缓存策略(重要!否则影响性能)
# 将原来的 nginx.conf 放回去
docker exec novalon-nginx-secure nginx -s reload

方法 B:版本化静态资源(长期方案)

如果你的项目使用了 next.config.ts 中的 assetPrefix,Next.js 会自动为静态资源添加 hash:

旧版本: /_next/static/css/abc123.css
新版本: /_next/static/css/def456.css

这样浏览器会自动请求新的 URL,无需手动清除缓存。


📞 紧急联系人列表

角色 姓名 电话/微信 职责 备注
值班工程师 待填写 待填写 执行回滚操作 第一响应人
技术负责人 待填写 待填写 决策是否回滚 P0/P1 故障需其批准
产品负责人 待填写 待填写 评估业务影响 P1/P2 故障需通知
运维支持 待填写 待填写 服务器/DNS 层面支持 当涉及基础设施问题时
Sentry 告警接收人 dev-team@novalon.cn - 错误监控告警 Sentry 配置

📊 回滚后复盘模板(必填!)

每次回滚完成后,必须在 24 小时内填写此模板并发送到团队群:

## Novalon Website 回滚复盘报告

**基本信息**
- 回滚日期和时间: 
- 发现问题时间: 
- 开始回滚时间: 
- 回滚完成时间: 
- 总宕机时间: ___ 分钟

**问题分类**
- [ ] 代码 Bug(哪个 commit 引入的?commit hash: _____
- [ ] 依赖兼容性问题(哪个包升级导致?包名及版本: _____
- [ ] 配置错误(nginx/docker/env?具体是哪个配置?)
- [ ] 第三方服务故障(CDN/DNS/SSL 证书?服务商是谁?)
- [ ] 其他: _____

**问题根因分析**
(详细描述为什么会出现这个问题)

**影响范围评估**
- 影响用户数估算: 约 ___ 人
- 受影响的页面/功能: 
- 是否造成数据丢失: 是/否(如果是,哪些数据?)
- 业务损失估算: 

**回滚操作详情**
- 回滚类型: Type 1 (代码回滚) / Type 2 (Docker 容器级) / Type 3 (CDN 清理)
- 回滚前版本: 
- 回滚后版本: 
- 是否成功恢复: 是/否
- 是否需要后续修复: 是/否

**改进措施(防止再次发生)**
1. 
2. 
3.

**如何改进测试/CI 流程以提前发现问题**
- [ ] 补充单元测试覆盖(具体是哪个模块?)
- [ ] 增加 E2E 测试用例(具体场景是什么?)
- [ ] 在 CI Pipeline 中增加质量门禁(什么条件?)
- [ ] 接入 Sentry 错误监控(已完成 ✓)
- [ ] 完善 Code Review 流程(什么标准?)
- [ ] 其他:

**经验教训总结**
(用一两句话总结这次回滚学到了什么)

**附件**
- 截图/日志: (如有)
- 相关 Issue/PR 链接: (如有)

🔧 常见问题排查(FAQ

Q1:回滚后网站仍然显示旧内容?

ACDN 缓存未刷新。解决方案:

  1. 执行 Type 3: CDN 缓存清理
  2. 或等待 CDN TTL 过期(通常 1-2 小时)
  3. 或使用 Ctrl+Shift+R 强制刷新浏览器缓存

Q2Git checkout 失败,提示"有未提交的更改"?

A:先暂存或丢弃这些更改:

# 查看有哪些未提交的更改
git status

# 方案 A:暂时保存(推荐)
git stash push -m "temp-save"

# 方案 B:直接丢弃(谨慎!不可逆)
git reset --hard HEAD

# 然后再执行 git checkout

Q3npm run build:clean 构建失败?

A:可能的原因及解决方法:

  1. 依赖未安装完全:运行 rm -rf node_modules && npm install
  2. TypeScript 类型错误:运行 npx tsc --noEmit 查看详细错误
  3. ESLint 错误:运行 npm run lint 查看详情
  4. 内存不足:增加 Node.js 内存限制 NODE_OPTIONS=--max-old-space-size=4096 npm run build:clean

Q4SSH 连接到服务器失败?

A:检查以下几点:

  1. 网络连接ping 139.155.109.62
  2. SSH 服务ssh -v root@139.155.109.62(查看详细日志)
  3. 防火墙:确认端口 22 未被封锁
  4. SSH Key:确认私钥文件权限正确 (chmod 600 ~/.ssh/id_rsa)

Q5:回滚后发现数据库或其他动态内容丢失?

A:对于纯静态网站(你的情况),不存在这个问题!

  • Novalon Website 是纯静态导出,不依赖数据库
  • 所有内容都在 dist/ 目录中
  • 回滚只是替换静态文件,不会影响任何持久化数据

快速参考卡片(打印出来贴在工位上)

╔══════════════════════════════════════════╗
║     Novalon Website 紧急回滚速查表       ║
╠══════════════════════════════════════════╣
║                                          ║
║  P0 触发条件:                            ║
║  • 首页白屏 / 5xx 错误                   ║
║  • 安全漏洞                              ║
║  • 域名/SSL 问题                         ║
║                                          ║
║  快速回滚命令(3 步完成):                ║
║                                          ║
║  1. git log --oneline -10               ║
║     # 找到稳定版本的 commit              ║
║                                          ║
║  2. git checkout <stable-commit-hash>   ║
║     # 切换到稳定版本                     ║
║                                          ║
║  3. ./deploy-dist.sh                    ║
║     # 重新构建并部署                     ║
║                                          ║
║  验证命令:                                ║
║  curl -I https://novalon.cn/            ║
║  # 预期: HTTP/2 200                      ║
║                                          ║
║  紧急联系人:                              ║
║  • 值班工程师: [姓名] - [电话]           ║
║  • 技术负责人: [姓名] - [电话]           ║
║  • 运维支持: [姓名] - [电话]             ║
║                                          ║
║  服务器信息:                              ║
║  IP: 139.155.109.62                      ║
║  用户: root                               ║
║  域名: novalon.cn                        ║
║  容器: novalon-nginx-secure              ║
║                                          ║
║  目标恢复时间: < 10 分钟                  ║
╚══════════════════════════════════════════╝

回滚完成清单

请在回滚完成后逐项确认:

立即确认(回滚后 5 分钟内)

  • 网站首页可访问,无白屏
  • HTTP 状态码返回 200
  • 关键页面(About, Contact, Products)可访问
  • 导航栏正常工作
  • SEO 元数据完整(title, description, OG tags
  • 已通知相关人员(邮件/群消息)

后续确认(回滚后 24 小时内)

  • 填写回滚复盘报告
  • 分析问题根因并记录
  • 制定预防措施
  • 更新 CI/CD Pipeline(如有必要)
  • 团队内部分享经验教训

📚 相关文档链接


💡 最后提醒

  • 保持冷静,按照步骤执行
  • 每一步都要验证再继续
  • 记录所有操作,方便事后复盘
  • 回滚不是失败,是负责任的表现!

祝你好运!🍀