feat(docs): restructure appendix content into organized directories

- Move standalone AI-related files into 8-artificial-intelligence directory
- Move development tools content into 2-development-tools directory
- Move server/backend content into 4-server-and-backend directory
- Create new index files for each section
- Update .gitignore to exclude old backup directories
- Update theme imports for new component locations
This commit is contained in:
sanbuphy
2026-02-15 01:57:52 +08:00
parent 004496f1d5
commit 07d82d046b
120 changed files with 409 additions and 405 deletions
@@ -0,0 +1,701 @@
# CI / CD 自动化
::: tip 🎯 核心问题
**代码在本地跑得好好的,怎么让全世界的人都能访问?**
:::
---
## 1. 为什么要"服务上线"
想象一下,你在自己家里做了一桌子菜,非常好吃。但问题是,只有自家人能吃到,邻居、保安、陌生人他们都尝不到。
怎么办?你需要**把菜端到餐厅里**。这就是"服务上线"要做的事——把你写的代码,从个人电脑,搬到一个7×24小时永远开着的"公共电脑"上。这样任何人只要能上网,就能访问你的网站。
<DeploymentOverviewDemo />
服务上线涉及很多环节。就像开餐厅不仅仅是端菜出去,你还需要租店面、装修、办执照、雇服务员等。开发网站也是同理。从代码到用户能访问的网站,中间隔着很多步骤。需要一步步完成构建、部署、配置网络、保证安全等工作。
下面我会把整个流程拆开来讲。每个环节都掰碎、揉细。保证连完全没基础的小白也能看懂。
---
## 2. 构建:把代码变成"可携带的包裹"
### 2.1 为什么要构建?
新手常问:代码写好了,为什么不能直接放到服务器上让用户访问?
要回答这个问题,先搞清楚你写的代码是什么格式。你可能用 Vue、React、Express、Koa 等框架。这些框架有一个共同特点:**它们不是给浏览器或服务器直接用的**。
举个例子。你写 Vue 代码时,是不是用过 `<template>``<script setup>` 这种标签?这种语法只有 Vue 认识。浏览器根本看不懂。浏览器只认识三种语言:HTML(网页结构)、CSS(网页样式)、JavaScript(网页逻辑)。Vue 组件语法对浏览器来说就像天书,完全无法理解。
所以在把代码放到服务器之前,必须做一件重要的事:**把它翻译成浏览器能看懂的语言**。这个翻译过程叫做"构建"Build)。
### 2.2 构建具体做什么?
构建不只是翻译。它还会做很多优化。让网站跑起来更快、更省资源。详细说说它具体都干了哪些活:
**第一步:解析依赖**
写代码时,会用到各种第三方库。比如 Vue、Vue Router、Axios、Vite 等。这些库不可能每次都让用户从 npm 下载。那样太慢了。构建工具会分析代码,把所有依赖找出来。然后把它们"打包"到一起。
**第二步:编译转换**
这是最核心的一步。把 Vue 组件编译成 HTML 和 JavaScript。把 SASS/LESS 编译成 CSS。把 ES6+ 新语法转换成兼容性更好的 ES5 代码。这步完成后,代码就从"开发者能看懂的格式"变成"机器能执行的格式"。
**第三步:压缩混淆**
压缩就是把所有空格、换行、注释删掉。把变量名从英文单词改成单个字母。比如 `userName` 变成 `a``calculateTotalPrice` 变成 `b`。这样文件大小大幅减小。用户下载起来就快多了。混淆后的代码人类基本看不懂。也能起到一点"保护代码"的作用。
**第四步:代码分割**
可能写了10个页面。每个页面有自己的代码。但用户可能只访问其中一个页面。为什么要下载其他9个页面的代码?构建工具会把代码分割成多个小块。用户访问哪个页面就下载哪个页面的代码。这就是"按需加载"。能大幅提升首次访问的速度。
**第五步:生成哈希**
这是非常重要的一步。但很多人会忽略。构建完成后,文件名会变成类似 `app.abc123.js``vendor.def456.css` 这样的格式。后面那串字母数字混合的字符串叫"哈希"。
哈希的作用是:当代码有任何改动时,哈希值就会变化。浏览器就知道"这个文件变了,需要重新下载"。没变的文件,浏览器继续使用缓存。不用重复下载。这样既能保证用户看到最新代码,又能充分利用缓存提升速度。
<DeploymentBuildDemo />
### 2.3 怎么执行构建?
大多数现代前端项目都已经配好构建工具。只需要记住一个命令:
```bash
# 如果用 npm
npm run build
# 如果用 yarn
yarn build
# 如果用 pnpm
pnpm build
```
运行完后,去项目根目录找一个叫 `dist` 的文件夹(有时也叫 `build``.output`)。里面就是构建好的所有文件。这些文件就是最终要上传到服务器的东西。不需要再做任何修改。直接拖到服务器上就行。
### 2.4 构建产物里有什么?
打开 dist 文件夹,会看到里面主要是三类文件:
- **HTML文件**:通常叫 `index.html`。这是入口文件。浏览器首先加载的就是它。
- **JS文件**:所有 JavaScript 代码。可能是1个也可能是好几个。
- **CSS文件**:所有样式代码。可能内联在 HTML 里,也可能是单独的 CSS 文件。
如果是比较复杂的后端项目(比如 Node.js),构建产物可能是一个可执行文件,或者一个 Docker 镜像。但原理是一样的:把代码变成服务器能直接运行的形式。
---
## 3. 服务器:找一台永远不关门的"房子"
### 3.1 服务器到底是什么?
很多人第一次听到"服务器",觉得是什么高大上的神秘设备。其实没那么复杂。**服务器就是一台电脑**。一台永远不关机、一直插着网线的电脑。
可能有人问:我自己家里不是有电脑吗?为什么要额外花钱租服务器?
这个问题问得好。帮你分析一下:
首先,你家的电脑不可能24小时开着。你要出门、要睡觉、偶尔还会死机重启。但服务器不一样。它专门用来干这个。可以365天全年无休地运行。网站随时都能访问。
其次,你家的网络也不行。家用宽带的上传速度通常很慢。而且家用宽带的 IP 是动态变化的。今天是这个 IP,明天可能就变成另外一个了。根本没法用来做网站服务器。服务器用的是数据中心的高速网络。IP 固定,网速飞快。
第三,你家的电脑没有"公网IP"。什么叫公网IP?就是全世界独一无二的地址。只有有这个地址,别人才能在互联网上找到你的电脑。你家电脑的 IP 通常只能在你家局域网里用。外面的人根本找不到你。服务器就不同了。它有一个固定的公网 IP。全世界的人都能通过这个 IP 找到它。
<DeploymentServerDemo />
### 3.2 怎么选服务器?
选服务器主要看三个指标:**CPU核数**、**内存大小**、**硬盘空间**。这三个指标越高,服务器性能越好,价格也越贵。
对于刚入门的新手,完全没必要买特别贵的配置。记住一个简单的选法:
- **个人项目、学习练手**:1核2G内存,足够了。一个月大概几十块钱。
- **小型商业项目**:2核4G内存。能承载每天几千到几万访问量。
- **中型项目**:4核8G或更高。需要专业团队来运维了。
还有一个要考虑的点:**地域**。如果用户主要在中国,就买国内的服务器(阿里云、腾讯云),访问速度快。如果用户主要在海外,就买国外的服务器(AWS、Google Cloud、DigitalOcean),或者买香港的服务器。速度快而且不用备案。
### 3.3 国内还是国外?
这是个很重要的问题。很多人刚开始没想清楚。后期会遇到麻烦。
**买国内服务器**的好处是速度快、延迟低。缺点是需要备案(提交网站信息给国家相关部门审核)。通常要等一周到一个月。而且国内服务器价格相对贵一些。
**买国外服务器**的好处是不用备案。买了就能用。价格也可能更便宜。缺点是中国大陆用户访问速度可能慢一些。如果是香港或新加坡机房会好很多。
建议是:如果是个人项目、学习展示用的网站,买香港或海外的服务器。省去备案的麻烦。如果是做正规商业项目,需要长期运营,就买国内服务器。老老实实备案,后期会省很多麻烦。
### 3.4 主流云厂商对比
| 厂商 | 适合人群 | 特点 | 新用户价格 |
|------|---------|------|-----------|
| 阿里云 | 国内业务 | 市场占有率第一,生态完善 | 首年几十到一百多 |
| 腾讯云 | 小程序、游戏 | 小程序云开发支持好 | 首年优惠力度大 |
| 华为云 | 企业用户 | 政府、政务项目首选 | 价格偏高 |
| DigitalOcean | 开发者 | 简单好用,价格透明 | $4/月起 |
| Vercel | 前端项目 | 零配置,直接推送就上线 | 免费额度够用 |
新手最推荐 **阿里云****腾讯云** 的学生机/新用户优惠。通常一年只需要几十块钱。性价比极高。如果做的是纯前端项目,想省事,也可以直接用 **Vercel****Netlify**。连服务器都不用买。把代码推送上去就自动部署好了。
### 3.5 拿到服务器后该做什么?
买完服务器后,会收到一封邮件。里面包含几个重要信息:
- **IP地址**:一串类似 `123.45.67.89` 的数字。这是服务器在互联网上的门牌号。
- **登录用户名**:通常是 `root`(管理员账号)。
- **登录密码**:初始密码,或者是让你设置密码的链接。
有了这些信息,就可以用 **SSHSecure Shell** 远程登录到服务器上。对它进行各种配置。SSH 就像是给服务器发的一条加密的远程控制命令。让自己电脑上就能操作远在天边的服务器。
登录命令是这样的:
```bash
ssh root@123.45.67.89
# 按回车后会让你输入密码。输入正确的密码后就登录成功了。
```
登录成功后,就进入了服务器的命令行界面。看起来和在自己电脑上开了一个终端窗口差不多。可以在这里安装软件、创建文件夹、修改配置。一切操作都和本地电脑一样。
---
## 4. 部署:把代码搬进"房子"
### 4.1 部署是什么?
部署就是租好了服务器(房子)之后,把代码(行李家具)搬进去。然后打开门开始营业的过程。
具体来说,部署包括以下几个步骤:
1. **把代码上传到服务器**:把构建产物从本地电脑传到服务器上。
2. **安装依赖**:服务器上可能没有项目需要的各种包。需要安装。
3. **配置环境变量**:比如数据库密码、API密钥等敏感信息。
4. **启动服务**:让应用程序跑起来。开始监听用户的请求。
这四个步骤听起来挺复杂。但其实做起来没那么难。下面会详细介绍每一步怎么做。
<DeploymentServerDemo />
### 4.2 怎么把代码上传到服务器?
**方法一:FTP/SFTP 上传**
这是最直观的方式。就像用网盘一样。把文件拖到服务器上。可以在自己电脑上下载一个叫 **FileZilla** 的免费软件。填入服务器的IP、用户名、密码。就能像管理本地文件一样管理服务器上的文件了。
**方法二:Git 拉取**
这是更推荐的方式。先在 GitHub、GitLab 或 Gitee 上创建一个代码仓库。把代码推送到云端。然后在服务器上用 `git clone` 命令把代码拉下来。
这样好处是:后续更新代码只需要在服务器上执行 `git pull` 命令就行。不用每次都手动上传。而且代码存云端也安全。服务器重装了也不怕。
**方法三:CI/CD 自动部署**
这是最专业的方式。也是强烈推荐的方式。通过配置 CI/CD(持续集成/持续部署),只需要把代码推送到 GitHub。CI/CD 系统就会自动帮你完成:拉取代码 → 安装依赖 → 构建 → 部署的全过程。甚至不需要登录服务器。一切都是自动完成的。
### 4.3 部署的具体步骤
假设用最简单的方式——Git 手动部署。一步步演示整个过程:
**第一步:连接到服务器**
```bash
ssh root@123.45.67.89
```
**第二步:安装必要的软件**
如果是 Node.js 项目,需要先安装 Node.js
```bash
# 以 Ubuntu 系统为例
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
```
**第三步:拉取代码**
```bash
# 创建放网站的目录
mkdir -p /var/www/my-website
cd /var/www/my-website
# 克隆代码仓库(需要先在GitHub上创建好仓库)
git clone https://github.com/你的用户名/你的仓库名.git .
```
**第四步:安装依赖并构建**
```bash
# 安装项目依赖
npm install
# 构建项目(生成 dist 目录)
npm run build
```
**第五步:用 PM2 启动服务**
为什么要用 PM2?它是一个进程管理工具。可以让网站在后台持续运行。就算服务器重启了也能自动启动。
```bash
# 全局安装 PM2
sudo npm install -g pm2
# 启动网站(假设入口文件是 index.js)
pm2 start index.js
# 设置开机自启
pm2 startup
pm2 save
```
**第六步:配置 Nginx 反向代理**
Node.js 应用通常跑在 3000 或 8080 这样的端口上。但用户访问的是 80 端口(HTTP默认端口)。需要用 Nginx 把 80 端口的请求转发到应用端口。
```bash
# 安装 Nginx
sudo apt install -y nginx
# 创建 Nginx 配置文件
sudo nano /etc/nginx/sites-available/my-website
```
在打开的编辑器里写入以下配置:
```nginx
server {
listen 80;
server_name example.com www.example.com;
# 静态文件(构建产物)直接返回
location / {
root /var/www/my-website/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
# API 请求转发到 Node.js 后端
location /api/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
保存退出后,启用这个配置:
```bash
# 启用配置
sudo ln -s /etc/nginx/sites-available/my-website /etc/nginx/sites-enabled/
# 测试配置是否有错误
sudo nginx -t
# 重启 Nginx
sudo systemctl restart nginx
```
现在访问 `http://example.com`(记得先把域名解析到这个服务器IP),应该就能看到网站了!
---
## 5. 域名和 DNS:给网站起个好名字
### 5.1 为什么要买域名?
有了服务器 IP,为什么还要买域名?
想想看。让你记住一串数字 `123.45.67.89` 是不是很困难?是不是很容易敲错?但让你记住 `baidu.com``taobao.com` 这样的名字是不是就简单多了?
域名就是网站的名字。好记、专业。还能体现品牌形象。想象一下。告诉别人"访问我做的网站,IP 是 123.45.67.89",和"访问 woshishuaige.com",哪个更像那么回事?
<DeploymentDnsDemo />
### 5.2 DNS 是什么?
好。现在买了一个域名。比如叫 `my-awesome-website.com`。但问题来了:电脑只认识 IP 地址。不认识 "my-awesome-website.com" 这种人类语言啊。
这就需要 DNS 出场了。DNS 的全称是 "Domain Name System"。翻译过来就是"域名系统"。可以把它理解成一本巨大的"电话簿"。专门负责把人类好记的域名翻译成电脑能看懂的 IP 地址。
当在浏览器里输入 `my-awesome-website.com` 并回车时。背后发生了这些事情:
1. 浏览器问 DNS"heymy-awesome-website.com 的 IP 地址是多少?"
2. DNS 查了一下"电话簿",告诉浏览器:"它的 IP 是 123.45.67.89"
3. 浏览器根据这个 IP 地址,找到了服务器,发出了请求
整个过程通常只需要几十毫秒。用户完全感知不到。
### 5.3 怎么配置 DNS
配置 DNS 通常有两个地方可以操作:
**方式一:在域名购买商那里配置**
在哪里买的域名,就去哪里配置 DNS 记录。最常见的记录类型是 **A 记录**
- **记录类型**A
- **主机记录**:通常填 `@`(代表域名本身,如 my-awesome-website.com)或者 `www`(代表 www.my-awesome-website.com
- **记录值**:服务器 IP 地址,如 `123.45.67.89`
**方式二:使用第三方 DNS 服务**
很多专业玩家不用域名商自带的 DNS。而是用 Cloudflare、阿里云 DNSPod、腾讯云 DNS 这些专业的 DNS 服务商。这些服务通常更稳定、解析速度更快。还自带 CDN、DDoS 防护等增值功能。
### 5.4 DNS 生效要多久?
这是很多人关心的问题。答案是:**不一定。通常几分钟到 24 小时**。
DNS 修改后,全球所有的 DNS 服务器需要同步这个变更。这就像往大海里扔一颗石子。波浪需要时间才能传到远方。有些 DNS 服务器更新快,几分钟就生效了。有些比较慢,可能需要等很久。
可以用以下命令检查 DNS 是否生效:
```bash
# Windows
ping 你的域名
# Mac/Linux
ping 你的域名
```
如果 ping 得通,显示的是服务器的 IP。说明 DNS 已经生效了。
---
## 6. HTTPS:给网站装一把"锁"
### 6.1 HTTP 和 HTTPS 的区别
可能注意到了。有些网站地址是 `http://` 开头的。有些是 `https://` 开头的。这个"s"很重要。它代表"安全"Secure)。
**HTTPHyperText Transfer Protocol** 是用来传输网页的协议。可以把它理解成运输数据的卡车。但这辆卡车是**透明的**。里面装的东西所有人都能看见。在 HTTP 网站上输入的密码、填写的个人信息。在传输过程中可能被中间的任何人偷看到。
**HTTPSHTTP Secure** 是给这辆卡车加了一个**密封的集装箱**。还配了一把钥匙。只有发送方和接收方有钥匙。中间的人就算截获了也看不懂里面是什么东西。这就是加密传输。
<DeploymentHttpsDemo />
### 6.2 为什么要 HTTPS
第一个原因:**安全**。没有 HTTPS,用户在网站上输入的密码是明文传输的。但凡有点技术的人都能截获。这年头,谁敢用没有 HTTPS 的网站?
第二个原因:**浏览器警告**。现在 Chrome、Edge 这些主流浏览器都会对没有 HTTPS 的网站显示"不安全"的警告。用户一看 warning 图标。跑了都来不及。更别说注册、充值了。
第三个原因:**SEO**。Google、百度这些搜索引擎都会优先收录 HTTPS 的网站。SEO 效果会更好。
### 6.3 怎么获取 HTTPS 证书?
以前 HTTPS 证书很贵。每年要花几百甚至几千块钱。现在好了。出了一个叫 **Let's Encrypt** 的组织。提供完全免费的 SSL/TLS 证书。而且社区有很多自动化工具帮你安装和续期。
**方式一:使用 Certbot(推荐)**
Certbot 是一个自动申请和配置 Let's Encrypt 证书的工具。非常简单:
```bash
# 安装 Certbot
sudo apt install -y certbot python3-certbot-nginx
# 一键申请证书并配置 Nginx
sudo certbot --nginx -d example.com -d www.example.com
```
运行过程中会问几个问题。比如邮箱(用于证书到期提醒)。回答完后证书就自动配置好了。访问网站会发现地址栏多了一个小锁🔒。
证书有效期是 90 天。但 Certbot 会帮你设置定时任务自动续期。基本不用管它。
**方式二:使用 Cloudflare**
如果使用了 Cloudflare 的 DNS 服务。那 HTTPS 证书根本不用自己配置。Cloudflare 会自动为域名提供 HTTPS 支持。而且连 90 天续期的问题都帮你解决了。
### 6.4 配置 HTTPS 后发生了什么变化?
配置好 HTTPS 后,用户访问从原来的 `http://example.com` 变成了 `https://example.com`。这个变化带来了一系列的安全保障:
1. **加密传输**:用户和服务器之间的所有通信都是加密的。
2. **身份验证**:证书可以证明"我真的是这个网站"。防止钓鱼网站。
3. **数据完整性**:能检测到数据是否被篡改。
---
## 7. CI/CD:让机器人帮你干活
### 7.1 什么是 CI/CD
CI/CD 是两个词的缩写:**C**ontinuous **I**ntegration(持续集成)和 **C**ontinuous **D**eployment(持续部署)。可以理解为一套帮你自动干活的机器人系统。
在没有 CI/CD 的时候。每次要发布新功能。流程是这样的:
1. 打开电脑,登录 GitHub
2. 拉取最新代码
3. 运行测试,看看有没有bug
4. 手动构建项目
5. 登录服务器
6. 拉取最新代码
7. 安装依赖
8. 构建项目
9. 重启服务
这9个步骤。每次发布都要手动做一遍。烦不烦?而且很容易漏掉某一步。比如忘记运行测试、忘记重启服务等。
有了 CI/CD 之后。流程变成了这样:
1. 把代码 push 到 GitHub
2. 喝茶坐等
3. (机器人自动完成上面9个步骤)
4. 网站自动更新了
<DeploymentCicdDemo />
这就是 CI/CD 的魅力:**只需要把代码推上去。剩下的全部自动完成**。
### 7.2 CI/CD 的工作流程
一个典型的 CI/CD 流程是这样的:
**第一步:代码提交(Push**
完成了新功能的开发。把代码 push 到 GitHub。
**第二步:CI(持续集成)触发**
GitHub 检测到代码变动。通知 CI 系统(GitHub Actions、GitLab CI 等)开始工作。
**第三步:安装依赖和测试**
CI 系统会启动一台虚拟电脑。在上面:
- 安装项目需要的各种依赖
- 运行测试代码,确保没有 bug
- 构建项目,生成产物
如果测试失败。CI 会发邮件通知。这次部署就停了。不会把有问题的代码部署到生产环境。
**第四步:CD(持续部署)执行**
测试全部通过后。CI 系统会:
- 通过 SSH 连接到服务器
- 拉取最新代码
- 安装依赖
- 构建项目
- 重启服务
整个过程可能只需要几分钟。全部自动完成。
### 7.3 怎么配置 GitHub Actions
GitHub Actions 是 GitHub 自带的 CI/CD 功能。不需要额外付费(免费额度足够个人项目用)。配置起来也非常简单。
在项目根目录下创建 `.github/workflows/deploy.yml` 文件。写入以下配置:
```yaml
name: Deploy to Production
# 触发条件:每当 main 分支有代码推送时
on:
push:
branches: [main]
# 任务列表
jobs:
# 部署任务
deploy:
# 在什么系统上运行
runs-on: ubuntu-latest
# 具体步骤
steps:
# 1. 检出代码
- name: Checkout code
uses: actions/checkout@v3
# 2. 安装 Node.js 环境
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
# 3. 安装依赖并构建
- name: Install and Build
run: |
npm ci
npm run build
# 4. 部署到服务器
- name: Deploy to Server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/my-website
git pull origin main
npm install
npm run build
pm2 restart all
```
这个配置文件告诉 GitHub Actions
- 当 main 分支有新代码时触发
- 在一台 Ubuntu 电脑上执行任务
- 先安装 Node.js 18
- 然后安装依赖并构建项目
- 最后通过 SSH 连接到服务器,执行一系列部署命令
配置好之后。每次 `git push origin main`。GitHub 就会自动开始部署。非常方便。
---
## 8. 监控和日志:做网站的"守夜人"
### 8.1 为什么要监控?
网站上线后。理论上应该 7×24 小时不间断运行。但现实世界没有这么美好。服务器可能会宕机。网络可能会抖动。代码可能会有bug。在真实的生产环境中。各种意外情况都有可能发生。
如果没有监控。就只能等用户打电话告诉你"网站打不开了"。这时候往往已经晚了。用户可能已经流失了。
有了监控之后。可以:
- **提前发现问题**:CPU 使用率 90% 了。提前加服务器。
- **快速定位问题**:网站慢了。查监控看是哪里瓶颈。
- **心里有底**:每天多少人访问、访问量什么时候最高。
<DeploymentMonitorDemo />
### 8.2 监控哪些指标?
最重要的监控指标就这几个:
| 指标 | 正常范围 | 超过怎么办 |
|------|---------|-----------|
| CPU 使用率 | < 70% | 升级服务器配置或优化代码 |
| 内存使用率 | < 80% | 检查是否有内存泄漏 |
| 磁盘使用率 | < 80% | 清理日志或无用文件 |
| 网站可达性 | 100% | 检查服务是否正常运行 |
| 响应时间 | < 2 秒 | 优化数据库查询或加缓存 |
| 错误率 | < 1% | 查看错误日志定位问题 |
### 8.3 怎么配置监控?
**最简单的方案:Uptime Robot**
注册 uptimerobot.com。添加网站URL。它会每 5 分钟自动检查一次网站是否正常。网站挂了会发邮件通知你。免费版本可以监控 50 个网站。对个人项目来说完全够用。
**进阶方案:阿里云/腾讯云监控**
如果服务器是在阿里云或腾讯云买的。它们自带监控功能。配置一下阈值报警就行。
**专业方案:Prometheus + Grafana**
这两个是监控领域的"瑞士军刀"。功能非常强大。可以监控任何能想到的指标。还能做出漂亮的可视化图表。不过配置起来比较复杂。适合有一定经验的开发者。
### 8.4 日志:出了问题怎么查?
监控告诉你"网站出问题了"。但具体是什么问题、为什么出问题。需要靠**日志**来定位。
日志就是程序运行时的"日记本"。记录了程序运行过程中的点点滴滴:
- 哪个用户在什么时候访问了什么页面
- 数据库查询花了多长时间
- 有没有报错,错误信息是什么
**最基础的日志用法**
在服务器上查看应用日志:
```bash
# 查看 PM2 的日志
pm2 logs
# 查看 Nginx 的访问日志
tail -f /var/log/nginx/access.log
# 查看 Nginx 的错误日志
tail -f /var/log/nginx/error.log
```
**进阶的日志方案**
如果项目比较复杂。推荐使用专业的日志收集工具:
- **Loki**:免费开源。和 Prometheus 一家的。
- **ELKElasticsearch + Logstash + Kibana**:功能强大。但配置复杂。
- **Sentry**:专门用于收集应用错误的工具。能自动收集报错信息。
### 8.5 告警:出问题怎么第一时间知道?
监控告诉你有问题。但如果没有盯着监控面板看,怎么办?这就需要**告警**了。
告警就是当监控系统检测到异常时。自动通过短信、微信、钉钉、邮件等方式通知你。可以设置不同的告警级别:
- **紧急(网站完全挂掉)**:发短信+打电话。必须马上知道。
- **严重(错误率飙升)**:发钉钉/微信消息。看到就处理。
- **一般(CPU 偏高)**:发邮件汇总。一天看一次就行。
告警配置的核心原则是:**分级告警,别把自己烦死**。如果什么鸡毛蒜皮的小事都给你发短信。用不了多久你就会把告警关掉。
---
## 9. 常见问题速查表
| 问题现象 | 可能原因 | 解决方法 |
|---------|---------|---------|
| 网站打不开 | 域名没解析 / 服务器挂了 / Nginx 没启动 | `ping 域名` 看通不通;`pm2 list` 看服务状态;`systemctl status nginx` 看 Nginx |
| 打开是空白页面 | 构建产物路径不对 / 静态文件没正确配置 | 检查 Nginx 的 root 路径是否指向 dist 目录 |
| 404 页面找不到 | 路由没正确配置 / 路径拼写错误 | Nginx 配置里加上 `try_files $uri $uri/ /index.html` |
| 502 Bad Gateway | 后端服务挂了 / 端口没开 | `pm2 list` 看进程是否在运行;检查端口是否正确 |
| 403 Forbidden | 权限不对 / 索引目录没开 | 检查文件权限 `chmod -R 755`Nginx 配置加上 `autoindex on` |
| HTTPS 证书过期 | 证书到期没续期 | `certbot renew` 手动续期;检查自动续期定时任务 |
| 更新后看不到变化 | 浏览器缓存 / CDN 缓存 | Ctrl+Shift+R 强制刷新;去 CDN 控制台"刷新缓存" |
| 网站打开很慢 | 带宽不够 / 没开缓存 / 没配置 CDN | 升级服务器带宽;配置 Redis 缓存;接入 CDN |
| 数据库连不上 | 数据库没启动 / 密码错了 / 权限问题 | 检查数据库服务状态;核对配置里的连接信息 |
---
## 总结
服务上线是一个系统性的大工程。涉及从代码构建到服务器部署、从网络配置到安全防护、从监控告警到日志分析的方方面面。对于初学者来说。不需要一开始就追求完美。先把最小可用版本(MVP)跑起来。然后在此基础上逐步完善。
整个流程的核心要点可以归纳为以下几点:
### 核心流程
1. **构建** → 用 `npm run build` 把代码变成浏览器能看懂的 HTML/CSS/JS
2. **部署** → 把构建产物上传到服务器。用 Nginx 配置反向代理。
3. **域名** → 购买域名并配置 DNS 解析到服务器 IP
4. **HTTPS** → 用 Let's Encrypt 申请免费证书。保护数据传输安全。
5. **CI/CD** → 配置自动化部署。代码 push 后自动上线。
6. **监控** → 配置监控和告警。出问题第一时间知道。
### 学习路线建议
- **第1天**:用 Vercel/Netlify 部署一个静态网页。体验一下"代码变成网站"的感觉。
- **第1周**:租一台云服务器。手动部署一个 Node.js 项目。配置域名和 HTTPS。
- **第2-4周**:配置完整的 CI/CD 流程。建立监控和告警体系。
- **持续学习**:学习 Docker 容器化、学习 Kubernetes 集群、学习微服务架构。
---
## 名词速查表
| 名词 | 英文 | 用人话解释 |
|------|------|-----------|
| 构建 | Build | 把源代码翻译打包成浏览器能执行的格式 |
| 部署 | Deploy | 把代码放到服务器上让用户能访问 |
| 服务器 | Server | 7×24小时不关机、联网的电脑 |
| 域名 | Domain | 网站的好记名字(如 baidu.com |
| DNS | Domain Name System | 把域名翻译成 IP 地址的"电话簿" |
| HTTP | HyperText Transfer Protocol | 网页传输协议(不安全,明文传输) |
| HTTPS | HTTP Secure | 加密传输的网页协议(安全) |
| Nginx | Engine X | 高性能 Web 服务器。做反向代理的。 |
| 反向代理 | Reverse Proxy | 站在门口的服务员。把请求转发给后端。 |
| SSH | Secure Shell | 远程登录服务器的加密工具 |
| CDN | Content Delivery Network | 全球分布的服务器网络。加快访问速度。 |
| CI/CD | Continuous Integration/Deployment | 自动化流水线。代码 push 后自动测试部署。 |
| SSL/TLS | Secure Sockets Layer / Transport Layer Security | 加密协议。给 HTTPS 提供安全保障。 |
| PM2 | Process Manager 2 | Node.js 进程管理器。让应用持续运行。 |
@@ -0,0 +1,759 @@
# 云身份与权限管理
> **学习指南**:提示词工程解决的是"怎么把话说清楚",云账号权限管理解决的是"谁能做什么事"。本章节会围绕一个问题展开:**在云端世界里,如何既能方便地授权,又不把钥匙交给不该给的人?**
在开始之前,建议你先补两块"基础砖":
- **Token 是什么**:可以先阅读 [大语言模型入门](./llm-intro.md) 的「分词 & Token」部分。
- **Prompt 是什么**:如果你还不熟悉 System / User / Assistant 的基本结构,可以先看 [提示词工程](./prompt-engineering/)。
---
## 0. 引言:为什么刚上云就"踩雷"了?
<IamRamComparisonDemo />
很多人刚开始使用云服务时都会遇到类似的情况:
- 为了省事,直接把 AccessKey 写在代码里提交到 GitHub
- 给所有员工都开了"管理员权限",结果有人误删了生产数据库;
- 项目交接后,不知道谁手里还有旧员工的账号密码;
- 听说要开 MFA,但觉得"麻烦"就一直拖着没开。
直觉上,我们会以为是:**"这些员工安全意识不够"**。
但大多数时候,问题并不在于人,而在于**没有建立正确的权限管理体系**。
<IntroProblemReasonSolution />
面对这些挑战,单纯依靠"小心点操作"已经行不通了。我们需要一套系统的权限管理方法论,这正是**IAMIdentity and Access Management,身份与访问管理)**试图解决的问题。
---
## 1. 什么是 IAM/RAM?从"门禁系统"说起
### 1.1 类比:公司的智能门禁
想象一下,你们公司搬到了一栋新写字楼:
| 场景 | 没有 IAM 的做法 | 有 IAM 的做法 |
| :--------- | :----------------------------- | :------------------------------------------- |
| 新员工入职 | 给他一把能开所有门的万能钥匙 | 给他一张门禁卡,只能刷他办公区域的门 |
| 员工离职 | 钥匙丢了就丢了,也不知道谁拿着 | 立即在系统里注销他的门禁卡,所有门都打不开了 |
| 外包人员 | 把钥匙借给他几天 | 发临时门禁卡,设置3天后自动失效 |
| 访客 | 前台配一把钥匙给他 | 发一次性访客码,只能进会议室 |
**IAMIdentity and Access Management,身份与访问管理)**,就像是这套"智能门禁系统":
- **身份(Identity)**:谁?员工、外包、访客、应用程序
- **访问(Access)**:能进哪些门?能做什么操作?
- **管理(Management)**:怎么发钥匙、怎么收钥匙、怎么查记录
### 1.2 AWS IAM vs 阿里云 RAM
<IamRamComparisonDemo />
不同的云厂商都有自己的 IAM 实现:
| 云厂商 | 服务名称 | 核心概念 |
| :--------- | :----------------------------------- | :------------------------ |
| **AWS** | IAM (Identity and Access Management) | User、Group、Role、Policy |
| **阿里云** | RAM (Resource Access Management) | 用户、用户组、角色、策略 |
| **腾讯云** | CAM (Cloud Access Management) | 用户、用户组、角色、策略 |
| **华为云** | IAM | 用户、用户组、委托、策略 |
| **Azure** | Azure AD + RBAC | User、Group、Role、RBAC |
虽然名字不同,但**核心概念都是相通的**:
- **用户(User)**:代表一个具体的人或应用程序
- **用户组(Group)**:批量管理一批用户的权限
- **角色(Role)**:定义一组权限,可以被"扮演"
- **策略(Policy)**:具体的权限规则(允许/拒绝做什么)
---
## 2. 用户、组、角色:到底该用哪个?
### 2.1 三种"身份"的区别
<IdentityProviderDemo />
用一个办公室的场景来类比:
| 概念 | 类比 | 适用场景 | 特点 |
| :------------------ | :----------------------------- | :------------------- | :--------------------------------- |
| **用户(User** | 正式员工,有自己的工位和门禁卡 | 长期、稳定的团队成员 | 有永久凭证(密码、AK/SK) |
| **用户组(Group** | 部门,如"技术部"、"销售部" | 批量管理权限 | 不能登录,只是权限容器 |
| **角色(Role** | 临时访客证、外包临时卡 | 临时授权、跨账号访问 | 没有永久凭证,靠"扮演"获取临时凭证 |
### 2.2 真实案例:一个创业公司的权限演进
**阶段一:创始团队(2-3人)**
```
问题:直接用根账号(Root Account)登录控制台,因为"省事"
风险:根账号拥有所有权限,一旦泄露整个账号就废了
```
**阶段二:团队扩张(5-10人)**
```
改进:给每个人创建 IAM User,分配不同权限
问题:
- 运维小王离职了,他的 AK/SK 散落在哪些服务器上?
- 新来的前端需要 S3 只读权限,后端需要 RDS 权限,手动一个个配太麻烦
```
**阶段三:规范化(10-30人)**
```
改进:
1. 按角色创建 IAM Group
- Developers(开发):S3、EC2、RDS 读写
- DevOps(运维):全权限,但需要 MFA
- ReadOnly(只读):查看所有资源,不能修改
- QAs(测试):测试环境资源访问
2. 使用 IAM Role
- EC2 实例使用 Instance Profile,不再在服务器上放 AK/SK
- 跨账号访问用 Role Assume,不用共享 AK/SK
- CI/CD 用 OIDC Federation,不用存储长期凭证
```
**阶段四:多账号/企业级(30人+**
```
架构:
- Master Account(主账号):只用来管理账单和组织结构,不放任何资源
- Audit Account(审计账号):收集所有账号的日志
- Dev Account(开发账号):开发环境
- Staging Account(预发布账号):测试环境
- Prod Account(生产账号):线上环境,权限最严格
权限流转:
- 开发人员默认只有 Dev 账号的只读权限
- 需要修改生产环境时,提工单申请 Assume 到 Prod 的临时 Role
- 所有 Assume 操作都被 CloudTrail 记录,定期审计
```
---
## 3. 角色与策略:权限管理的"灵魂"
### 3.1 角色的本质:信任 + 权限
<RolePolicyDemo />
IAM Role 有两个核心组成部分:
1. **信任策略(Trust Policy**:谁可以扮演这个角色?
2. **权限策略(Permission Policy**:扮演成功后能做什么?
用一个话剧表演的类比:
| 概念 | 类比 | 说明 |
| :-------------------- | :--------------------- | :----------------------------------------------------------------------------------------- |
| **Role(角色)** | 剧本里的"哈姆雷特" | 定义了要演什么戏(权限) |
| **Trust Policy** | 导演说"谁能演哈姆雷特" | 可能是"本剧团的演员"(本账号用户)、"隔壁剧团借来的演员"(跨账号)、"特邀嘉宾"(外部 IdP |
| **Permission Policy** | 剧本内容 | 哈姆雷特能做什么:说台词、决斗、发疯(具体权限) |
| **Assume Role** | 演员上台表演 | 小李被导演选中演哈姆雷特,上台后他就拥有了剧本里定义的所有权限 |
| **临时凭证** | 演出证 | 小李拿到一个"临时演出证",演出结束后就失效了 |
### 3.2 策略(Policy):权限的"语法"
<PermissionHierarchyDemo />
IAM Policy 是一个 JSON 文档,定义了"谁能对什么资源做什么操作"。
**一个完整的 Policy 示例**
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3ReadWrite",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::my-app-bucket/*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "ap-northeast-1"
},
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
},
{
"Sid": "DenySensitiveData",
"Effect": "Deny",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-app-bucket/sensitive/*"
}
]
}
```
**关键字段解释**
| 字段 | 含义 | 示例 |
| :------------ | :--------------------------------- | :----------------------- |
| **Version** | Policy 语法版本 | "2012-10-17" |
| **Statement** | 权限声明数组,可包含多个规则 | [...] |
| **Sid** | 声明 ID,可选,用于标识这条规则 | "AllowS3ReadWrite" |
| **Effect** | 效果:Allow(允许)或 Deny(拒绝) | "Allow" |
| **Action** | 允许/拒绝的操作,支持通配符 | "s3:GetObject", "s3:\*" |
| **Resource** | 作用的资源,用 ARN 标识 | "arn:aws:s3:::bucket/\*" |
| **Condition** | 可选,满足特定条件时才生效 | 区域限制、MFA 要求等 |
### 3.3 权限的优先级:Deny > Allow > 默认拒绝
IAM 的权限评估逻辑可以用一句话总结:**显式 Deny 永远赢,没有 Allow 就是拒绝**。
评估流程如下:
```
1. 先看有没有 Deny 策略
├─ 有 Deny → 拒绝(不管有没有 Allow)
└─ 没有 Deny → 继续看
2. 再看有没有 Allow 策略
├─ 有 Allow → 允许
└─ 没有 Allow → 拒绝(默认拒绝原则)
```
**实战案例:保护敏感数据**
```json
// 策略1:给开发者的普通权限
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": "arn:aws:s3:::company-data/*"
}
// 策略2:保护敏感目录(即使开发者有 s3:* 也不能访问)
{
"Effect": "Deny",
"Action": ["s3:*"],
"Resource": "arn:aws:s3:::company-data/sensitive/*"
}
```
**关键点**
- 开发者虽然有 `s3:*` 的 Allow 权限
- 但敏感目录有显式的 Deny 规则
- Deny 优先级更高,所以开发者无法访问敏感数据
- 即使开发者是管理员,这个 Deny 也有效(除非是根账号)
---
## 4. 访问密钥(AK/SK):一把需要谨慎保管的"钥匙"
### 4.1 AK/SK 是什么?
<AccessKeyManagementDemo />
Access Key(访问密钥)是云服务提供的一种长期凭证,用于程序化的 API 调用。它由两部分组成:
| 组成部分 | 名称 | 作用 | 类比 |
| :-------------------- | :----------- | :------------------------- | :--------- |
| **Access Key ID** | 访问密钥 ID | 标识你是谁(类似于用户名) | 银行卡号 |
| **Secret Access Key** | 秘密访问密钥 | 证明你是你(类似于密码) | 银行卡密码 |
### 4.2 为什么 AK/SK 是"高危物品"
**真实案例:某创业公司的教训**
小李是一家创业公司的新晋后端工程师。入职第一周,他的任务是调试一个文件上传功能。
```python
# 小李写的代码(有严重安全问题!)
import boto3
# 为了方便调试,直接把 AK/SK 写在代码里
s3 = boto3.client(
's3',
aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
region_name='ap-northeast-1'
)
def upload_file(file_path, bucket_name, object_name):
s3.upload_file(file_path, bucket_name, object_name)
print(f"文件已上传到 s3://{bucket_name}/{object_name}")
# 测试上传
upload_file('./test.jpg', 'my-company-bucket', 'uploads/test.jpg')
```
**一周后发生的事情**
1. 小李提交代码到 GitHub(包括 AK/SK
2. GitHub 上的代码被爬虫扫描到,AK/SK 被提取
3. 攻击者使用这些凭证,在公司账号里创建了大量 EC2 实例挖矿
4. 月底收到账单:额外消费 12,000 美元
5. 审计发现 AK/SK 泄露,小李被约谈...
**这个案例告诉我们什么?**
| 错误做法 | 正确做法 |
| :-------------------------- | :----------------------------------------------- |
| 把 AK/SK 硬编码在代码中 | 使用 IAM Role,让程序自动获取临时凭证 |
| 把 AK/SK 提交到 Git 仓库 | 使用 `.gitignore` 忽略配置文件,使用密钥管理服务 |
| 长期使用同一个 AK/SK 不轮换 | 定期轮换 AK/SK,使用临时凭证替代长期凭证 |
| 给 AK/SK 分配过大权限 | 遵循最小权限原则,只授予必要的权限 |
### 4.3 AK/SK 的安全使用指南
**场景一:本地开发**
```bash
# 正确做法:使用 AWS CLI 配置凭证,不写在代码里
aws configure
# 然后根据提示输入 Access Key ID 和 Secret Access Key
# 这些信息会被保存在 ~/.aws/credentials,权限设置为 600
# 代码中不需要任何凭证配置
import boto3
s3 = boto3.client('s3') # 自动从 ~/.aws/credentials 读取
```
**场景二:服务器/EC2**
```python
# 正确做法:使用 IAM Instance Profile
# 1. 创建一个 IAM Role,附加需要的权限(如 S3ReadOnly)
# 2. 创建一个 Instance Profile,关联这个 Role
# 3. 启动 EC2 时,选择这个 Instance Profile
# 代码中完全不需要凭证
import boto3
s3 = boto3.client('s3') # 自动从 EC2 元数据服务获取临时凭证
# 临时凭证会自动轮换,无需担心过期
```
**场景三:CI/CD 流水线**
```yaml
# 正确做法:使用 OIDC FederationOpenID Connect
# 以 GitHub Actions 为例:
# 1. 在 AWS 创建 OIDC Identity Provider,信任 GitHub
# 2. 创建一个 IAM Role,信任策略允许 GitHub 的特定仓库扮演
# 3. 在 GitHub Actions 中配置
name: Deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # 关键:允许请求 OIDC token
contents: read
steps:
- uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
# 注意:这里没有 Access Key!完全使用临时凭证
- name: Deploy
run: aws s3 sync ./build s3://my-bucket/
```
**总结:AK/SK 使用的安全层级**
| 安全等级 | 做法 | 适用场景 | 风险等级 |
| :------- | :-------------------------- | :------------------------ | :------- |
| 最高 | 使用 IAM Role(无长期凭证) | EC2、Lambda、ECS、CI/CD | 极低 |
| 高 | 使用 OIDC Federation | GitHub Actions、GitLab CI | 低 |
| 中 | 使用密钥管理服务 | 本地开发、小团队 | 中 |
| 低 | 使用环境变量 | 快速原型、个人项目 | 高 |
| 极低 | 硬编码在代码中 | 任何场景都不推荐 | 极高 |
---
## 5. 多因素认证(MFA):给你的账号加把"锁"
### 5.1 什么是 MFA
<MfaSecurityDemo />
MFAMulti-Factor Authentication,多因素认证),也叫 2FATwo-Factor Authentication,双因素认证),是一种安全机制,要求用户在登录时提供**两种或以上**不同类型的认证因素:
| 因素类型 | 是什么 | 例子 |
| :------------------------- | :----------------- | :------------- |
| **知识因素**(你知道什么) | 只有用户知道的信息 | 密码、PIN 码 |
| **持有因素**(你有什么) | 用户拥有的物理设备 | 手机、硬件密钥 |
| **生物因素**(你是什么) | 用户的生物特征 | 指纹、面部识别 |
### 5.2 为什么 MFA 这么重要?
**真实数据告诉你答案**
| 攻击方式 | 没有 MFA 时的成功率 | 有 MFA 时的成功率 |
| :----------------------- | :------------------ | :------------------------------ |
| 密码猜测/暴力破解 | 很高 | 极低(还需要第二因素) |
| 钓鱼攻击获取密码 | 很高 | 极低(钓鱼页面无法获取 MFA 码) |
| 密码泄露(其他网站泄露) | 很高 | 极低(不知道第二因素) |
**微软安全报告(2020**:启用 MFA 可以阻止 **99.9%** 的自动化攻击。
### 5.3 MFA 实战:为 AWS 根账号开启 MFA
**步骤一:登录 AWS 控制台**
1. 使用根账号邮箱和密码登录
2. 在右上角点击你的账号名,选择 "Security Credentials"
**步骤二:启用 MFA**
1. 找到 "Multi-factor authentication (MFA)" 区域
2. 点击 "Assign MFA device"
3. 选择 MFA 设备类型(推荐"Authenticator app"
**步骤三:配置虚拟 MFA**
1. 在手机上安装 Google Authenticator 或 Microsoft Authenticator
2. 扫描二维码或手动输入密钥
3. 输入 App 上显示的 6 位验证码(连续输入两个,因为验证码每 30 秒刷新)
**完成!** 你的根账号现在有了 MFA 保护。
---
## 6. 跨账号访问:如何安全地"串门"?
### 6.1 为什么需要跨账号访问?
<CrossAccountAccessDemo />
随着业务增长,很多公司会使用**多账号架构**来隔离不同环境:
| 账号类型 | 用途 | 权限要求 |
| :------------------ | :--------------------- | :----------------- |
| **Master Account** | 组织管理、账单结算 | 几乎不使用 |
| **Security Audit** | 集中收集所有账号的日志 | 只读访问其他账号 |
| **Shared Services** | 共享资源(镜像仓库等) | 其他账号只读访问 |
| **Development** | 开发环境 | 开发者完全权限 |
| **Staging** | 测试/预发布环境 | 测试人员权限 |
| **Production** | 生产环境 | 严格限制,需要审批 |
**问题:Shared Services 账号里的镜像,怎么让 Production 账号的 EC2 拉取?**
- 方案 A:把 AK/SK 写在 Production 的用户数据里 (危险!AK/SK 泄露风险)
- 方案 B:使用跨账号 Role Assume (推荐!临时凭证,自动轮换)
### 6.2 跨账号 Role Assume 的原理
```
账号 AProduction 账号 BShared Services
| |
| 1. 请求 Assume Role |
| "我想扮演账号 B 的 ECRReadRole" |
|------------------------------------------>|
| |
| 2. 检查信任策略 |
| "账号 A 可以扮演我吗?" |
| |
| 3. 返回临时凭证 |
| AccessKeyId, SecretKey, SessionToken |
|<------------------------------------------|
| |
| 4. 使用临时凭证访问 ECR |
| docker pull 账号B.dkr.ecr... |
```
**关键点**
- 临时凭证有效期默认 1 小时,最长可配置 12 小时
- 不需要在代码里存储任何长期凭证
- 信任策略可以限制谁可以扮演这个角色(如指定账号、指定外部 ID)
### 6.3 实战:配置跨账号 ECR 访问
**场景**Production 账号的 EC2 需要拉取 Shared Services 账号的 Docker 镜像。
**步骤一:在 Shared Services 账号创建 IAM Role**
1. 登录 Shared Services 账号的 AWS 控制台
2. 进入 IAM -> Roles -> Create role
3. 选择"Another AWS account"
4. 输入 Production 账号的 Account ID
5. 可选:勾选"Require external ID"并输入一个随机字符串(增加安全性)
6. 附加权限:AmazonEC2ContainerRegistryReadOnly
7. 给 Role 命名:CrossAccountECRReadRole
**步骤二:获取 Role ARN**
创建完成后,复制 Role 的 ARN:
```
arn:aws:iam::SHARED_SERVICES_ACCOUNT_ID:role/CrossAccountECRReadRole
```
**步骤三:在 Production 账号配置 EC2 实例**
方式 A:使用 Instance Profile(推荐)
1. 在 Production 账号创建 IAM RoleEC2 用)
2. 信任策略:信任 EC2 服务
3. 权限策略:允许 Assume 跨账号 Role
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::SHARED_SERVICES_ACCOUNT_ID:role/CrossAccountECRReadRole"
}
]
}
```
4. 创建 Instance Profile,关联这个 Role
5. 启动 EC2 时,选择这个 Instance Profile
方式 B:在 EC2 用户数据里动态 Assume Role
```bash
#!/bin/bash
# 安装 AWS CLI
yum install -y aws-cli
# Assume 跨账号 Role
CREDS=$(aws sts assume-role \
--role-arn arn:aws:iam::SHARED_SERVICES_ACCOUNT_ID:role/CrossAccountECRReadRole \
--role-session-name EC2PullSession)
# 提取临时凭证
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r '.Credentials.SessionToken')
# 登录 ECR
aws ecr get-login-password --region ap-northeast-1 | \
docker login --username AWS --password-stdin SHARED_SERVICES_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com
# 拉取镜像
docker pull SHARED_SERVICES_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest
```
**步骤四:测试跨账号访问**
在 Production 的 EC2 上执行:
```bash
# 测试能否 Assume Role
aws sts get-caller-identity
# 应该显示:arn:aws:sts::PRODUCTION_ACCOUNT_ID:assumed-role/CrossAccountECRReadRole/EC2PullSession
# 测试能否列出 Shared Services 的 ECR 仓库
aws ecr describe-repositories --registry-id SHARED_SERVICES_ACCOUNT_ID
```
**完成!** 现在 Production 的 EC2 可以安全地拉取 Shared Services 的镜像,而无需共享任何长期凭证。
---
## 7. 实战:构建安全的权限体系
### 7.1 从零开始搭建权限架构
<BestPracticesDemo />
假设你是一个 10 人创业公司的技术负责人,需要从零设计 AWS 权限架构。以下是推荐的实施步骤:
**阶段一:根账号保护(第 1 天)**
```
目标:保护根账号,这是最重要的账号
1. 启用根账号 MFA(必须)
- 推荐硬件 MFAYubiKey),或者 Google Authenticator
2. 创建 IAM 管理员账号
- 用户名:admin(或你的名字)
- 权限:AdministratorAccess(但后续会收紧)
- 启用 MFA
3. 删除根账号的 Access Key(如果创建了的话)
- 根账号永远不应该有 AK/SK
4. 配置根账号使用告警
- 使用 CloudWatch + SNS,一旦根账号登录就发邮件/短信
```
**阶段二:团队权限分组(第 1 周)**
```
目标:给团队成员分组,批量管理权限
1. 分析团队角色:
- 后端开发(2人)
- 前端开发(1人)
- 移动端开发(1人)
- 产品经理(1人)
- 设计师(1人)
- 创始人/管理员(3人)
2. 创建 IAM Groups
Group: Developers
├── 成员:所有开发(后端、前端、移动端)
├── 权限:
│ ├── EC2: 启动、停止、查看(但不能删除别人的实例)
│ ├── S3: 读写开发环境的 bucket
│ ├── RDS: 只读权限(不能修改生产数据库)
│ └── CloudWatch: 查看日志
└── 限制:只能操作 ap-northeast-1 区域
Group: ProductTeam
├── 成员:产品经理、设计师
├── 权限:
│ ├── S3: 只读(查看数据文件)
│ ├── CloudWatch Dashboard: 查看监控图表
│ └── Cost Explorer: 查看账单(但不能修改)
└── 限制:只读权限,不能修改任何资源
Group: Administrators
├── 成员:创始人、技术负责人
├── 权限:AdministratorAccess
└── 要求:必须使用 MFA 才能操作
3. 给每个人创建 IAM User,加入对应的 Group
- 不要给个人直接附加权限,一律通过 Group 管理
- 启用 MFA(强制要求)
```
**阶段三:应用层权限优化(第 2-4 周)**
```
目标:让应用程序安全地访问 AWS 资源
1. EC2 实例使用 Instance Profile
- 不再在服务器上配置 AK/SK
- 创建 IAM Role,附加需要的权限(如 S3 读写)
- 创建 Instance Profile,关联这个 Role
- 启动 EC2 时选择这个 Instance Profile
- 应用代码中直接使用 boto3,无需配置凭证
2. 如果必须使用 AK/SK(第三方集成)
- 使用 AWS Secrets Manager 存储 AK/SK
- 应用启动时从 Secrets Manager 读取
- 设置定期轮换(90天)
- 监控 AK/SK 的使用情况
3. 配置 CloudTrail 记录所有 API 调用
- 创建单独的 S3 bucket 存储日志
- 设置日志文件校验(防止篡改)
- 配置 SNS 通知关键事件(如根账号使用、策略变更)
```
**阶段四:安全加固(持续)**
```
目标:建立持续的安全监控和改进机制
1. 启用 AWS Config
- 监控资源配置变更
- 检查合规性(如安全组是否开放了 0.0.0.0/0)
2. 启用 IAM Access Analyzer
- 持续分析资源策略
- 识别外部访问(如 S3 bucket 是否公开)
3. 定期审查 IAM 配置
- 每月检查一次未使用的 IAM User、Role
- 检查 Access Key 的使用情况
- 验证 Group 成员是否合理
4. 建立安全事件响应流程
- 如果发现 AK/SK 泄露:立即删除、轮换、审计影响范围
- 如果发现异常 API 调用:立即调查、限制权限
```
---
## 8. 常见误区与避坑指南
### 8.1 十大 IAM 反模式
| # | 反模式 | 为什么不好 | 正确做法 |
| :-- | :--------------------------- | :--------------------------------------------- | :----------------------------------------------- |
| 1 | 使用根账号进行日常操作 | 根账号拥有所有权限,一旦泄露无法限制损害 | 创建 IAM 管理员账号,根账号仅在必要时使用 |
| 2 | 给所有人 AdministratorAccess | 违反最小权限原则,增加误操作和内部威胁风险 | 按角色分组,只授予必要的权限 |
| 3 | 在代码中硬编码 AK/SK | AK/SK 容易通过 GitHub 泄露,且难以轮换 | 使用 IAM Role、环境变量或密钥管理服务 |
| 4 | 长期不轮换 AK/SK | 增加凭证泄露后的风险敞口时间 | 设置 90 天轮换策略,或更好的——使用临时凭证 |
| 5 | 忽略 MFA | 密码泄露后账号直接沦陷 | 为所有 IAM 用户启用 MFA,尤其是高权限用户 |
| 6 | 不使用 CloudTrail | 无法审计谁做了什么操作,出事后无法溯源 | 启用 CloudTrail,并将日志存储到独立的审计账号 |
| 7 | IAM Policy 过于宽松 | 如 `Resource: "*"``Action: "*"`,增加攻击面 | 明确指定资源 ARN 和具体 Action |
| 8 | 不清理离职员工的 IAM User | 僵尸账号可能成为后门 | 建立离职流程,立即禁用并删除 IAM User |
| 9 | 不使用 IAM Access Analyzer | 无法发现过度宽松的资源策略(如公开 S3 bucket | 启用 IAM Access Analyzer,定期检查外部访问 |
| 10 | 不在测试环境验证 Policy | 直接在生产环境应用 Policy,可能导致服务中断 | 使用 IAM Policy Simulator 测试,先在测试环境验证 |
---
## 9. 名词对照表
| 英文术语 | 中文对照 | 解释 |
| :--------------------------------------- | :-------------- | :----------------------------------------- |
| **IAM (Identity and Access Management)** | 身份与访问管理 | 云服务中管理用户身份和访问权限的服务 |
| **RAM (Resource Access Management)** | 资源访问管理 | 阿里云的 IAM 服务名称 |
| **Root Account** | 根账号 | 注册云账号时创建的拥有者账号,拥有最高权限 |
| **IAM User** | IAM 用户/子账号 | 由根账号创建的子身份,用于日常操作 |
| **IAM Role** | IAM 角色 | 临时性权限载体,无长期凭证,需要被"扮演" |
| **IAM Policy** | IAM 策略 | JSON 格式的权限规则定义 |
| **ARN** | 亚马逊资源名称 | 全局唯一的资源标识符 |
| **AK/SK** | 访问密钥/密钥 | 程序访问云 API 的凭证 |
| **STS** | 安全令牌服务 | 提供临时安全凭证的服务 |
| **MFA** | 多因素认证 | 需要两个或以上因素的认证方式 |
| **SSO** | 单点登录 | 用户一次登录即可访问多个系统的认证方式 |
| **ExternalId** | 外部 ID | 用于防止困惑代理攻击的安全标识符 |
| **CloudTrail** | 云审计服务 | 记录云账号中所有 API 调用和操作的日志服务 |
---
## 总结:云账号权限管理的核心原则
云账号权限管理不是一蹴而就的,而是需要根据团队规模和业务需求持续演进:
1. **起步阶段**1-10 人):
- 保护根账号(MFA + 不用根账号日常操作)
- 创建 IAM 管理员账号
- 基本的分组(Developers、Admins
2. **成长阶段**10-50 人):
- 细化的权限分组(前后端、运维、产品等)
- 使用 IAM Role 替代 AK/SK
- 启用 CloudTrail 审计
- 定期权限审查
3. **成熟阶段**50 人以上 / 多账号):
- 多账号架构(Dev、Staging、Prod 分离)
- 集中式日志审计账号
- 自动化权限审查和告警
- 完善的权限申请和审批流程
**核心原则记住三句话**
1. **最小权限原则**:只给必要的权限,不要给 AdministratorAccess
2. **不用长期凭证**:优先使用 IAM Role 和临时凭证,避免 AK/SK 泄露
3. **启用 MFA**:特别是根账号和高权限账号,这是最有效的安全措施
---
> **延伸阅读**
>
> - [AWS IAM 官方文档](https://docs.aws.amazon.com/iam/)
> - [阿里云 RAM 官方文档](https://www.aliyun.com/product/ram)
> - [AWS IAM Best Practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
@@ -0,0 +1,262 @@
# 云平台实战
> **学习指南**:云服务厂商不是"买服务器的网站",而是"像水电公司一样提供计算能力的基础设施"。本章节会围绕一个核心问题展开:**从零开始,如何理解并使用云服务?** 我们会用真实场景、生动类比和实战步骤,帮你建立云服务的完整认知地图。
在开始之前,建议你先了解:
- **基础网络概念**:如果你还不熟悉 IP 地址、端口、域名等概念,建议先阅读 [网络基础知识](/zh-cn/appendix/computer-networks)
- **API 是什么**:如果你对 API 还不了解,可以先看 [API 入门](/zh-cn/appendix/api-intro)
---
## 0. 引言:为什么越来越多公司不买服务器了?
想象一下这个场景:
小明在 2010 年创业,想做一个网站。他经历了什么?
他先花 2 万块钱买了一台戴尔服务器,然后联系 IDC 机房,每个月付 3000 元托管费。接着自己安装 Linux、配置环境,还要担心硬件问题——硬盘坏了要自己换,机器过热要自己解决。最痛苦的是,当用户突然多了,系统撑不住了,他又要买新服务器。一年后,小明花了 5 万,服务器利用率却只有 10%。
而小红的公司在 2024 年创业,她是怎么做的?
她打开云服务商网站,注册账号,点几下鼠标就创建了一台云服务器,2 分钟完成。用多少付多少,不用不花钱。流量大了,点一下升级配置。想开美国分部?换个地域就行。一个月后,小红花了 500 元,服务器利用率 80%。
**直觉上,我们会以为是:"云服务就是租服务器"。**
但云服务的本质远不止于此——它是一场**计算能力的革命**。
过去,企业要经历买服务器、找机房、装系统、担心硬件、流量暴增时束手无策的漫长过程。现在,只需要注册账号、点几下鼠标、按需付费、自动扩容、全球部署。这种转变,就像从自家挖井取水,变成了打开水龙头就有自来水。
---
## 1. 什么是云服务厂商?
### 1.1 像水电公司一样的计算服务
云服务厂商的本质,是**把计算能力、存储能力、网络能力包装成标准化的服务**,像自来水公司提供水、电力公司提供电一样,通过互联网提供给用户使用。
这种模式的聪明之处在于**按需使用**。你不需要提前购买大量硬件,只需要根据实际使用量付费。需要更多资源?点一下就行。有些服务甚至按秒计费,极其灵活。而且云服务厂商在几十个国家都有数据中心,你可以在全球范围内部署应用,所有操作都是自助服务,24 小时都能进行,不需要人工审批。
### 1.2 云服务与传统托管的区别
传统 IDC 托管就像自己买发电机发电。你需要先买硬件(服务器),然后找地方放(机房托管),还要自己维护(装系统、修硬件)。如果电力不够用了,你得再买一台发电机。这个过程可能需要几天到几周,成本是固定的,不管用不用都要付钱。
云服务则像接入电网。你不需要买发电机,只需要拉一根电线(注册账号),然后按用电量付费。需要更多电力?换个更大功率的套餐就行,几分钟搞定。这种模式下,成本是可变的,用多少付多少,而且云厂商负责所有硬件维护,你只需要关注自己的业务。
### 1.3 公有云、私有云与混合云
就像餐厅有不同的经营模式,云服务也有三种类型。
**公有云**就像公共餐厅,谁都能用,资源共享。AWS、阿里云、Azure 都是公有云,适合绝大多数企业和个人。这是本书的重点,因为它最常用、最适合学习。
**私有云**就像私人厨房,自己搭建,独享资源。OpenStack、VMware 是典型代表,适合大型企业、政府、银行这些对数据安全要求极高的场景。
**混合云**则是两者结合,一部分业务用公有云,一部分用私有云。各厂商都有解决方案,适合既需要合规又需要弹性的场景。
👇 **动手点点看**
点击下方的服务卡片,了解云服务的六大核心类别。
<CloudServicesOverview />
---
## 2. 著名的云服务厂商有哪些?
### 2.1 国际三巨头:AWS、Azure、Google Cloud
在全球云服务市场,有三家厂商占据了主导地位。
**AWSAmazon Web Services** 是亚马逊 2006 年推出的云服务,全球市场份额第一,约 32%。它就像云服务界的"百货商店",服务种类最全,有 200 多种服务,功能最成熟稳定,文档和社区资源也最丰富。价格虽然偏高,但性价比很好,特别适合出海企业、初创公司和大型互联网公司。
**Microsoft Azure** 是微软 2010 年推出的云服务,全球市场份额第二,约 23%。它最大的优势是与 Windows、Office 生态深度集成,企业级客户资源丰富,混合云能力强,对 .NET 开发者特别友好。如果你的公司已经在用微软技术栈,Azure 是自然而然的选择。
**Google Cloud Platform (GCP)** 是谷歌 2011 年推出的云服务,全球市场份额第三,约 10%。它在 Kubernetes、数据分析、AI 领域领先,技术创新能力强,价格相对便宜。但市场份额较小,生态不如前两家完善,适合技术驱动型公司、容器化应用和 AI 项目。
### 2.2 国内三巨头:阿里云、腾讯云、华为云
在中国云服务市场,同样有三家主要厂商。
**阿里云** 是阿里巴巴 2009 年成立的云计算部门,中国市场份额第一,约 40%。作为国内最早、最成熟的云服务商,阿里云服务种类齐全,电商、双十一技术积累深厚。虽然价格相对较高,但稳定性和功能完整性都是一流的,特别适合国内企业和电商相关项目。
**腾讯云** 是腾讯 2013 年成立的云服务部门,中国市场份额第二,约 15%。它在游戏、音视频能力强,与微信、QQ 生态结合好,价格相对便宜,近几年发展迅速。如果你做游戏、社交或直播类项目,腾讯云是不错的选择。
**华为云** 是华为 2015 年成立的云服务部门,中国市场份额第三,约 10%。它硬件技术积累强,政府和企业客户资源丰富,安全合规能力强,AI 芯片(昇腾)有特色。适合政府项目、大型国企和制造业。
### 2.3 如何选择云服务商?
选择云服务商就像选择租房,要考虑位置、价格、配套设施等多个因素。
**首先看目标市场**。你的用户主要在哪里?如果用户在中国,选阿里云或腾讯云;如果用户在海外,选 AWS 或 Azure;如果是全球业务,选有多地域覆盖的厂商。
**其次看技术栈**。你用的是什么技术?如果用微软技术,选 Azure;如果用 Kubernetes、大数据,选 Google Cloud;如果是通用场景,AWS 是个稳妥的选择。
**再看成本**。小项目试水可以选便宜的,比如腾讯云或 UCloud;大规模生产则要看总体成本,AWS 长期可能更省钱。
**最后看生态**。如果你已经在用其他服务,比如 GitHub、Office 365,选同生态的厂商会更方便。
现实建议是:初学者或小项目选阿里云或腾讯云,因为文档是中文,客服在国内;出海项目选 AWS,因为它最成熟、全球覆盖最好;大企业可能需要多云策略,不同业务用不同云。
---
## 3. 一般怎么用云服务?
### 3.1 从注册到上线的完整流程
使用云服务的第一步是注册账号。这个过程就像在银行开户,需要验证你的身份。打开云服务商官网,点击"免费注册",填写邮箱和密码,验证手机号,然后上传身份证或企业资质进行实名认证,最后绑定支付方式。整个过程大约需要 10 到 20 分钟。
注册完成后,你需要了解几个核心概念。**地域(Region)** 是云服务的数据中心所在地区,比如华东(杭州)、美东(弗吉尼亚)、亚太(新加坡)。选择原则是离你的用户越近越好,因为延迟更低。**可用区(Availability Zone, AZ** 是一个地域内的多个数据中心,相互隔离,提高可用性。如果一个可用区挂了,另一个还能用。**实例(Instance)** 就是一台虚拟服务器,比如一台 2 核 4G 的云服务器,计费方式是按时长或按量。
### 3.2 创建第一台云服务器
创建云服务器的过程就像组装一台电脑,但是是在网页上点选配置。首先选择付费模式,测试环境用按量付费,长期运行用包年包月。然后选择地域,选离你最近的,比如华东-杭州。实例规格方面,2 核 4G 对于测试环境够用了。镜像选择操作系统,比如 CentOS 7.9 或 Ubuntu 20.04。存储用 40GB 系统盘,网络用默认 VPC 网络,带宽按使用流量付费比较省钱。最后设置 root 用户密码,记得保存好。整个过程大约 5 分钟,实例创建完成后等待 1 到 2 分钟即可使用。
👇 **动手点点看**
选择配置,了解不同规格的价格和适用场景。
<ComputeInstanceDemo />
### 3.3 连接云服务器并部署应用
连接 Linux 服务器推荐使用 SSH。用密码登录的方式是 `ssh root@你的服务器公网IP`,然后输入密码。用密钥登录更安全,方式是 `ssh -i 你的私钥.pem root@你的服务器公网IP`
连接上服务器后,你就可以部署应用了。首先更新系统,CentOS 用 `sudo yum update -y`Ubuntu 用 `sudo apt update && sudo apt upgrade -y`。然后安装必要软件,比如 Node.js。接着上传代码,可以用 git 或 scp。最后安装依赖并启动应用。
### 3.4 常见使用场景
**托管个人网站或博客** 需要云服务器加域名,1 核 2G 足够,成本约 50 到 100 元每月,技术栈可以用 Nginx 加静态文件或 WordPress。
**部署 API 后端** 需要云服务器加数据库,2 核 4G 起步,成本约 200 到 500 元每月,技术栈可以用 Node.js 或 Python 配合 MySQL 或 PostgreSQL。
**存储图片或视频** 推荐用对象存储,按存储量和流量计费,成本几元到几百元每月不等。优势是不用管硬盘,自动备份,还可以配合 CDN 加速。
👇 **动手点点看**
了解不同类型的云存储服务及其适用场景。
<StorageTypeDemo />
---
## 4. 如何购买和调用 API
### 4.1 云服务的计费模式
云服务的计费方式有很多种,理解它们能帮你省很多钱。
**按需付费(Pay-as-you-go** 就像单买电影票,用多少付多少,不用不花钱。适合测试环境、流量不稳定的项目。云服务器按小时计费,对象存储按 GB 加请求次数计费,AI API 按调用次数计费。
**包年包月或预留实例** 就像买月票或年票,承诺使用一定时长,享受折扣,通常能省 30% 到 60%。适合长期稳定运行的生产环境。比如一台 2 核 4G 服务器,按需 200 元每月,包 1 年可能只要 140 元每月。
**竞价实例或抢占式实例** 就像候补票,价格很低,最多能省 90%,但可能被强制回收。适合批处理任务、容错性高的任务,比如数据处理、渲染任务。风险是云厂商资源紧张时会强制收回实例。
**Serverless 按调用次数** 就像计程车,不用关心服务器,只关心调用次数。计费方式是调用次数加计算时间加流量,适合 API 接口、事件驱动任务。比如阿里云函数计算,前 100 万次调用免费,超出后 1.33 元每百万次。
👇 **动手点点看**
使用计费计算器,对比不同计费模式的成本差异。
<PricingCalculator />
### 4.2 购买 API 调用的完整流程
以调用通义千问 API 为例,整个流程分为四步。
**第一步是开通服务**。打开云厂商的 AI 开放平台或机器学习平台 PAI,找到通义千问或 DashScope,点击"立即开通"或"免费试用",大约 2 分钟完成。
**第二步是获取 API Key**。进入控制台的 API-KEY 管理,点击"创建我的 API-KEY",复制并保存这个 Key。重要提示:API Key 只显示一次,请立即保存。
**第三步是配置权限**。进入访问控制(RAM)或权限管理(IAM),创建一个用户或角色,只授权需要的权限,比如只能调用通义千问,不能删除服务器。这是最小权限原则。
**第四步是调用测试**。用 Python 或 JavaScript 发起第一次调用,验证 API 是否正常工作。
---
## 5. 实战:从零开始部署一个网站
### 5.1 场景与方案选择
假设你是一个前端开发者,想部署一个个人博客网站。需求是静态网站(HTML/CSS/JS),有自己的域名,全球访问速度快,成本尽量低。
有三种方案可选。云服务器方案成本中等,难度中等,适合需要后端服务的场景。对象存储加 CDN 方案成本低,难度低,适合纯静态网站,这是我们的推荐方案。Serverless 方案成本极低,难度中等,适合动态内容。
推荐对象存储加 CDN 的原因是:成本最低(可能免费),配置最简单,速度最快(CDN 加速)。
👇 **动手点点看**
按照步骤指引,了解部署网站的完整流程。
<DeployWorkflowDemo />
### 5.2 实施步骤
**第一步:准备网站文件**。创建一个简单的 index.html
```html
<!DOCTYPE html>
<html>
<head>
<title>我的博客</title>
</head>
<body>
<h1>欢迎来到我的博客</h1>
<p>这是我的第一篇文章。</p>
</body>
</html>
```
**第二步:创建对象存储 Bucket**。登录云控制台,找到对象存储(OSS/S3),点击"创建 Bucket"。配置名称(比如 my-blog-2024,全局唯一),选择地域(离你最近的),权限设置为公共读(网站需要被访问)。
**第三步:上传文件**。进入 Bucket,点击"上传文件",选择 index.html,等待上传完成。
**第四步:配置静态网站托管**。进入 Bucket 设置,找到"静态页面"或"网站托管",启用功能,设置默认首页为 index.html,保存配置。
**第五步:绑定域名(可选)**。购买域名(如阿里云万网),添加 CNAME 记录指向 Bucket 域名,在 Bucket 中绑定自定义域名,配置 HTTPS。
**第六步:配置 CDN(推荐)**。开通 CDN 服务,添加加速域名,选择源站(你的 Bucket),等待 CDN 生效(几分钟到几小时)。
### 5.3 成本估算
月度成本估算:对象存储 0 到 5 元(按存储量计费),CDN 流量 0 到 10 元(按流量计,有免费额度),域名 5 到 10 元(按年折算)。总计 5 到 25 元每月,小网站可能完全免费。
---
## 6. 总结与下一步
### 6.1 核心要点回顾
云服务的本质可以概括为:云服务厂商是计算能力的水电公司,提供按需使用、全球部署、自助服务的能力。使用流程是选择厂商、注册账号、创建资源、配置权限、监控成本。
关键决策点包括:选厂商要看市场、技术栈、成本;选计费模式要在按需、包年包月、Serverless 之间权衡;配权限要遵循最小权限原则,启用 MFA,定期审计;控成本要监控用量,使用折扣,及时释放不需要的资源。
### 6.2 学习路径建议
第一周学习理论基础,了解云服务基本概念,注册一个云账号,创建第一台云服务器。第二周动手实践,部署一个静态网站,配置域名和 CDN,学习基础 Linux 命令。第三周学习进阶技能,包括权限管理(IAM)、监控和告警、成本优化。第四周进行项目实战,部署一个完整的应用,配置数据库和存储,实现自动扩容。
### 6.3 推荐资源
官方文档包括阿里云文档中心、AWS 中文文档、腾讯云文档。学习平台有阿里云大学、AWS 免费套餐、腾讯云实验室。社区资源有云原生社区、Serverless 中文网、InfoQ 云计算专栏。
---
## 7. 名词对照表
| 英文术语 | 中文对照 | 解释 |
| :--- | :--- | :--- |
| **Cloud Provider** | 云服务厂商 | 提供云计算服务的公司,如 AWS、阿里云 |
| **Region** | 地域 | 数据中心所在的地理区域 |
| **Availability Zone** | 可用区 | 一个地域内的独立数据中心 |
| **Instance** | 实例 | 一台虚拟服务器 |
| **Image/AMI** | 镜像 | 预配置的操作系统模板 |
| **VPC** | 虚拟私有云 | 隔离的虚拟网络环境 |
| **IAM/RAM** | 身份与访问管理 | 权限管理系统 |
| **User** | 用户 | 一个具体的身份 |
| **Group** | 用户组 | 用户的集合 |
| **Role** | 角色 | 临时身份 |
| **Policy** | 策略 | 定义权限的 JSON 文档 |
| **API Key** | API 密钥 | 调用 API 的凭证 |
| **AccessKey** | 访问密钥 | 编程访问的凭证(ID + Secret |
| **MFA** | 多因素认证 | 需要密码加验证码的登录方式 |
| **CDN** | 内容分发网络 | 全球加速服务,缓存静态资源 |
| **OSS/S3** | 对象存储 | 存储文件的服务 |
| **ECS/EC2** | 云服务器 | 虚拟主机服务 |
| **RDS** | 关系型数据库服务 | 托管的数据库 |
| **Serverless** | 无服务器 | 不用管理服务器的计算模式 |
| **Pay-as-you-go** | 按需付费 | 用多少付多少的计费模式 |
| **Reserved Instance** | 预留实例 | 包年包月的计费模式 |
| **Spot Instance** | 抢占式实例 | 低价但可能被回收的实例 |
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,3 @@
# 域名、DNS 与 HTTPS
> 待实现
@@ -0,0 +1,3 @@
# Docker 容器化
> 待实现
@@ -0,0 +1,611 @@
# 网关与反向代理
::: tip 🎯 核心问题
**在高并发的互联网架构中,如何把流量安全、高效地送到正确的服务?** 反向代理解决"流量怎么分发",API网关解决"请求怎么处理"。本文通过真实案例(前台接待、保安系统、智能路由)深入理解网关的设计哲学和工程实践。
:::
---
## 1. 为什么要"网关"?
### 1.1 从一个真实案例说起:某电商的架构演进
某电商平台在业务快速增长时遇到了严重的架构问题:
**场景还原:**
```
阶段一:直接暴露服务
客户端 → 直接调用用户服务、订单服务、支付服务...
问题1:服务IP暴露,存在安全隐患
问题2:无法统一做认证、限流
问题3:新增服务需要修改客户端配置
```
::: warning ⚠️ 直接暴露的致命问题
- **安全隐患**: 所有服务IP暴露,容易被攻击
- **功能重复**: 每个服务都要做认证、限流、日志
- **扩展困难**: 新增服务要修改所有客户端
- **协议混乱**: 有的用HTTP,有的用gRPC,客户端要适配
:::
**改进后的架构(引入网关):**
```
客户端 → API网关(Nginx/Kong) → 内部服务
统一认证、限流、路由
客户端只知道网关地址
```
::: tip ✨ 改进后的效果
- **安全**: 真实服务IP隐藏,只有网关对外
- **功能收敛**: 认证、限流、日志在网关统一处理
- **扩展容易**: 新增服务只需网关配置路由
- **协议统一**: 对外HTTP,内部可用gRPC
:::
### 1.2 网关的生活化比喻
**前台接待**
想象你去一家大公司:
- **没有前台**: 访客直接找各部门,不知道在哪,公司乱成一团
- **有前台**: 访客先到前台,前台问清楚来意,再引导到对应部门
**API网关就是系统的"前台"**:
- **反向代理**: 前台,引导访客到正确的部门
- **API网关**: 智能前台,还能检查访客身份(认证)、限制访问人数(限流)
<ReverseProxyDemo />
---
## 2. 什么是反向代理?
### 2.1 正向代理 vs 反向代理
::: tip 🤔 术语解释
**正向代理(Forward Proxy)**:
- 部署在客户端侧
- 代替客户端访问外部资源
- 典型应用:VPN、翻墙工具
- 例子:公司网络,你通过代理访问外网
**反向代理(Reverse Proxy)**:
- 部署在服务器端
- 接收客户端请求并转发给内部服务
- 客户端只知道代理存在,不知道真实服务器
- 例子:Nginx、HAProxy
:::
**对比表:**
| 维度 | 正向代理 | 反向代理 |
| ------------ | ------------------------ | ------------------------ |
| **部署位置** | 客户端侧 | 服务器端 |
| **服务对象** | 客户端 | 服务器 |
| **典型应用** | VPN、翻墙 | 负载均衡、网关 |
| **透明性** | 服务器看到代理IP | 客户端看到代理IP |
| **目的** | 隐藏真实客户端、加速访问 | 隐藏真实服务器、负载均衡 |
### 2.2 反向代理的核心价值
::: details 价值一:负载均衡
将流量分发到多个后端服务器,避免单点过载。
```
客户端
Nginx(反向代理)
┌─────────┬─────────┬─────────┐
│ 服务器1 │ 服务器2 │ 服务器3 │
└─────────┴─────────┴─────────┘
```
:::
::: details 价值二:安全防护
隐藏真实服务器IP,防止直接攻击。统一在代理层做安全防护。
```
客户端 → 只能看到Nginx的IP
真实服务器 → 只在内网,外部无法直接访问
```
:::
::: details 价值三:SSL终结
在代理层处理HTTPS加密解密,后端服务用HTTP,降低后端计算开销。
```
HTTPS客户端 → Nginx(加密/解密) → HTTP后端服务
SSL终结点
```
:::
---
## 3. Nginx:为什么能扛起百万并发?
### 3.1 Master-Worker进程模型
Nginx采用**多进程**架构,而不是多线程:
**Master进程(管理者)**:
- 负责读取和验证配置文件
- 管理Worker进程(启动、停止、重新加载)
- 不处理具体请求
**Worker进程(工作者)**:
- 实际处理HTTP请求
- 每个Worker是独立的进程,相互隔离
- 数量通常设置为CPU核心数,避免上下文切换开销
::: tip 💡 优势
- **隔离性好**: 一个Worker崩溃,不影响其他Worker
- **充分利用多核**: 每个Worker独立运行
- **避免多线程复杂性**: 无需处理锁、竞争等问题
:::
### 3.2 事件驱动 + 异步非阻塞
这是Nginx高性能的核心秘密:
**传统Apache(多进程/线程模型)**:
- 一个连接 = 一个进程/线程
- 并发数受限于系统进程/线程数
- 大量连接时,进程切换开销巨大
**Nginx(事件驱动模型)**:
- 使用epoll(Linux)/kqueue(macOS)等高效I/O多路复用机制
- 一个Worker进程可以同时处理数万个连接
- 连接没有数据时,不会占用CPU,有新数据时通过事件通知唤醒
::: tip 生活化比喻
- **Apache**: 餐厅里每个顾客配一个服务员(进程),顾客多需要大量服务员
- **Nginx**: 一个超级服务员,同时服务所有顾客,谁需要服务就去谁那里,而不是一直站在某个顾客旁边
:::
<NginxArchitectureDemo />
---
## 4. 什么是API网关?
### 4.1 为什么需要API网关?
**想象一个没有网关的系统:**
- 客户端需要知道多个服务的地址(用户服务、订单服务、支付服务...)
- 每个服务都要自己做认证、限流、日志
- 协议不统一,有的用HTTP,有的用gRPC
- 服务升级时,客户端也需要跟着改
::: warning ⚠️ 没有网关的问题
- **客户端复杂**: 需要配置多个服务地址
- **功能重复**: 每个服务都要实现认证、限流
- **协议混乱**: 客户端要适配多种协议
- **升级困难**: 服务升级,客户端也要改
:::
**有了API网关之后:**
- 客户端只需要知道网关地址,网关负责路由到正确服务
- 认证、限流、日志等横切逻辑统一在网关处理
- 网关可以做协议转换,对外统一暴露HTTP
- 后端服务升级,只需要改网关配置,客户端无感知
<ApiGatewayDemo />
### 4.2 API网关的核心功能
| 功能 | 说明 | 典型场景 |
| :----------- | :----------------------------------------- | :----------------------------------------------- |
| **路由转发** | 根据URL、Header等规则,将请求转发到不同服务 | `/api/users` → 用户服务,`/api/orders` → 订单服务 |
| **负载均衡** | 同一个服务有多实例时,分摊流量 | 用户服务有3台实例,轮询分发请求 |
| **认证鉴权** | 统一校验JWT、OAuth Token | 未登录用户无法访问`/api/admin` |
| **限流熔断** | 控制流量上限,防止服务被压垮 | 每秒最多1000请求,超过返回429 |
| **协议转换** | 对外HTTP,内部可转gRPC | 客户端用HTTP,网关转gRPC调用内部服务 |
| **灰度发布** | 按Header或比例,将部分流量导到新版本 | 5%用户体验新版本,95%用旧版本 |
| **日志监控** | 统一记录请求日志,便于分析和排障 | 记录每次请求的耗时、状态码、返回大小 |
---
## 5. 网关实战:如何构建完整的网关架构?
### 5.1 完整架构图
```
┌───────────────────────────────────────────────────────────────────────┐
│ 客户端(浏览器/APP) │
└───────────────────────────┬─────────────────────────────────────────┘
│ HTTPS
┌───────────────────────────────────────────────────────────────────────┐
│ 外层:CDN + WAF │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ CDN(内容分发网络) │ │
│ │ - 静态资源缓存(图片、CSS、JS) │ │
│ │ - 就近访问,降低延迟 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ WAF(Web应用防火墙) │ │
│ │ - 防护SQL注入、XSS攻击 │ │
│ │ - 拦截恶意Bot、爬虫 │ │
│ │ - CC攻击防护 │ │
│ └───────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────┐
│ 中层:API网关(Nginx/Kong) │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第一层:SSL终结 + 安全防护 │ │
│ │ - HTTPS / TLS 1.3 │ │
│ │ - HSTS、安全响应头 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第二层:认证与鉴权 │ │
│ │ - JWT Token校验 │ │
│ │ - OAuth 2.0 / SSO集成 │ │
│ │ - API Key管理 │ │
│ │ - 权限校验(RBAC) │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第三层:流量控制 │ │
│ │ - 限流- 令牌桶/漏桶算法 │ │
│ │ - 熔断- 防止故障扩散 │ │
│ │ - 降级- 服务不可用时的备用方案 │ │
│ │ - 灰度发布- 按比例分配流量 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第四层:路由与负载均衡 │ │
│ │ - 路径路由- Path-based Routing) │ │
│ │ - 域名路由- Host-based Routing) │ │
│ │ - Header路由- Header-based Routing) │ │
│ │ - 负载均衡算法- 轮询/加权/最少连接/IP哈希) │ │
│ │ - 服务发现- Service Discovery)集成 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第五层:协议转换与数据处理 │ │
│ │ - SSL终结- HTTPS ↔ HTTP) │ │
│ │ - 协议转换- HTTP ↔ gRPC / WebSocket) │ │
│ │ - 请求/响应转换- JSON ↔ XML) │ │
│ │ - 数据压缩- Gzip / Brotli) │ │
│ │ - 缓存- Cache)- 静态资源和API响应 │ │
│ └───────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────┐
│ 内层:微服务集群 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 用户服务 │ │ 订单服务 │ │ 商品服务 │ │ 支付服务 │ │
│ │ User Svc │ │ Order Svc │ │ Product Svc │ │ Payment Svc │ │
│ │ │ │ │ │ │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └────────────────┴────────────────┴────────────────┘ │
│ │ │
│ 服务发现与配置中心/ etcd) │
│ - 服务注册与发现 │
│ - 健康检查 │
│ - KV配置存储 │
└───────────────────────────────────────────────────────────────────────┘
```
### 5.2 路由与负载均衡
网关的核心职责之一,就是**把请求送到正确的地方**。这涉及两个关键能力:**路由**(去哪台服务器)和**负载均衡**(怎么分配流量)。
::: details 路由规则:从URL到服务
想象一个电商系统,不同的URL对应不同的服务:
- `/api/users/*` → 用户服务
- `/api/orders/*` → 订单服务
- `/api/products/*` → 商品服务
- `/api/pay/*` → 支付服务
**Nginx配置示例:**
```nginx
server {
listen 80;
server_name api.example.com;
# 用户服务
location /api/users/ {
proxy_pass http://user-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 订单服务
location /api/orders/ {
proxy_pass http://order-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 商品服务
location /api/products/ {
proxy_pass http://product-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 支付服务(需要更高安全级别)
location /api/pay/ {
# 限制IP访问
allow 10.0.0.0/8;
deny all;
proxy_pass http://payment-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
:::
::: details 负载均衡:四种策略对比
当同一个服务有多个实例时,如何选择?
| 策略 | 原理 | 适用场景 | 优点 | 缺点 |
| :----------- | :------------------------------------------------ | :----------------- | :------------------- | :--------------------------- |
| **轮询** | 按顺序依次分配给每台服务器 | 服务器性能相近 | 简单公平 | 不考虑服务器当前负载 |
| **加权轮询** | 按权重比例分配,权重高的分配更多 | 服务器性能不均 | 充分利用高性能服务器 | 需要合理设置权重 |
| **最少连接** | 分配给当前连接数最少的服务器 | 长连接场景、视频流 | 动态适应负载变化 | 需要实时统计连接数 |
| **IP哈希** | 根据客户端IP计算哈希,同一IP永远分配到同一台服务器 | 需要会话保持 | 保证会话一致性 | 某个IP流量大时会造成单点压力 |
**Nginx配置示例:**
```nginx
# 加权轮询
upstream backend_weighted {
server 10.0.1.10:8080 weight=3; # 性能好,承担更多流量
server 10.0.1.11:8080 weight=2;
server 10.0.1.12:8080 weight=1; # 性能差,承担较少流量
}
# 最少连接
upstream backend_least_conn {
least_conn;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}
# IP哈希(会话保持)
upstream backend_ip_hash {
ip_hash;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}
```
:::
<LoadBalancingDemo />
---
## 6. 网关安全:如何守护系统大门?
### 6.1 认证与鉴权
**传统方式(每个服务各自认证):**
- 用户服务、订单服务、支付服务...每个都要校验JWT
- 代码重复,维护困难
- secret分散在各个服务,泄露风险高
**网关统一认证:**
- 客户端携带Token访问网关
- 网关校验Token合法性(签名、过期时间)
- 校验通过后,将用户信息(如user_id)添加到请求头,转发给后端服务
- 后端服务无需校验,直接从Header获取用户信息
::: tip 💡 核心思想
**认证在网关,鉴权在服务**:
- **认证**: 你是谁?(校验Token,获取用户身份)
- **鉴权**: 你能做什么?(根据用户角色判断权限)
就像公司前台:前台认证你的身份(身份证),但具体权限由各部门判断。
:::
<AuthMiddlewareDemo />
### 6.2 HTTPS与SSL终结
**为什么需要HTTPS?**
1. **安全**: 防止数据在传输过程中被窃取
2. **合规**: 现代浏览器对HTTP网站显示"不安全"警告
3. **SEO**: 搜索引擎优先收录HTTPS网站
**SSL终结方案:**
- 只在网关层配置HTTPS和证书
- 网关负责TLS握手和加解密
- 网关和后端服务之间使用HTTP明文传输(内部网络可信)
- 后端服务专注于业务逻辑,无需处理TLS
::: tip 💡 SSL终结的优势
- **简化管理**: 证书只在网关配置,后端无需配置
- **降低开销**: 后端服务不需要处理TLS握手
- **统一更新**: 证书更新只需在网关操作
:::
<SslTerminationDemo />
---
## 7. 限流与熔断:如何防止系统被"流量洪水"冲垮?
### 7.1 限流算法对比
| 算法 | 核心思想 | 突发流量 | 适用场景 | 实现复杂度 |
| :----------- | :------------------------ | :-------------------------- | :----------------------------- | :--------- |
| **令牌桶** | 桶里装令牌,有令牌才能通过 | 允许一定程度的突发 | API限流、带宽控制 | 中等 |
| **漏桶** | 请求进桶,匀速流出处理 | 强制平滑,突发会被缓存或拒绝 | 需要严格匀速处理的场景 | 中等 |
| **滑动窗口** | 统计时间窗口内的请求数 | 严格按窗口计数,超出一律拒绝 | 精确统计(如"1分钟内最多100次") | 较高 |
### 7.2 Nginx限流配置实战
```nginx
# 定义限流区域(放在http块中)
# 1. 基于IP的限流(漏桶算法)
# zone=mylimit:10m - 区域名称和内存大小(10MB约可存储16万IP)
# rate=10r/s - 每秒允许10个请求
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
# 2. 基于IP的连接数限制(防止单个IP建立过多连接)
limit_conn_zone $binary_remote_addr zone=addr:10m;
# 3. 基于服务端点的限流(不区分IP,保护后端整体)
limit_req_zone $server_name zone=server_limit:10m rate=100r/s;
server {
listen 80;
server_name api.example.com;
# 用户服务 - 普通限流
location /api/users/ {
# 应用限流
# burst=20 - 桶容量,允许突发20个请求
# nodelay - 不延迟处理突发请求(立即处理或拒绝)
limit_req zone=mylimit burst=20 nodelay;
# 限制单个IP的连接数
limit_conn addr 10;
proxy_pass http://user-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 订单服务 - 更严格的限流
location /api/orders/ {
# 更严格的限流:每秒5个请求
limit_req_zone $binary_remote_addr zone=order_limit:10m rate=5r/s;
limit_req zone=order_limit burst=10 nodelay;
proxy_pass http://order-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 限流后的处理
# 当请求被限流时,返回429 Too Many Requests
error_page 429 /429.html;
location = /429.html {
internal;
return 429 '{"error": "Too Many Requests", "message": "Rate limit exceeded. Please try again later."}';
add_header Content-Type application/json;
}
}
```
::: tip 💡 限流策略建议
- **普通接口**: 每秒10个请求,允许突发20个
- **重要接口**(支付、订单): 每秒5个请求,允许突发10个
- **全局保护**: 所有请求总和不超过每秒100个
:::
<RateLimitingDemo />
### 7.3 熔断:防止故障扩散
**熔断器的工作原理:**
1. **关闭状态**: 正常转发请求,同时统计错误率
2. **开启状态**: 当错误率超过阈值,熔断器开启,直接返回错误,不再转发请求
3. **半开状态**: 经过一段时间后,允许少量请求通过试探,如果成功则关闭熔断器
::: tip 💡 核心思想
**熔断就像电路保险丝**: 电流过大时,保险丝自动熔断,保护整个电路不被烧毁。
类似地,当后端服务出现大量错误时,熔断器"跳闸",快速失败,防止故障扩散到整个系统。
:::
---
## 8. 总结:网关设计的核心思维
### 8.1 核心原则回顾
| 原则 | 含义 | 实践要点 |
| ------------ | -------------------- | ------------------------------ |
| **路由** | 把请求送到正确的地方 | 路径路由、域名路由、Header路由 |
| **负载均衡** | 分摊流量到多台服务器 | 轮询、加权、最少连接、IP哈希 |
| **安全** | 守护系统大门 | 认证鉴权、HTTPS、WAF |
| **限流** | 防止被流量冲垮 | 令牌桶、漏桶、滑动窗口 |
| **熔断** | 防止故障扩散 | 快速失败、降级方案 |
| **可观测** | 监控和排障 | 日志、指标、链路追踪 |
### 8.2 技术选型建议
::: tip 💡 选型决策树
```
选择网关:
├─ 只需要反向代理、负载均衡?
│ ├─ 是 → Nginx(首选)
│ └─ 否 → 继续
├─ 需要丰富的插件生态?
│ ├─ 是 → Kong(基于Nginx)
│ └─ 否 → 继续
├─ Spring Cloud 全家桶?
│ ├─ 是 → Spring Cloud Gateway
│ └─ 否 → Nginx
```
:::
---
## 9. 名词速查表
| 名词 | 英文 | 解释 |
| ------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| **反向代理** | Reverse Proxy | 部署在服务器端,接收客户端请求并转发给内部服务的代理服务。客户端只知道反向代理的存在,不知道真实服务器地址。 |
| **正向代理** | Forward Proxy | 部署在客户端侧,代替客户端访问外部资源的代理服务。服务端看到的是代理的IP,不知道真实客户端。典型应用:VPN、翻墙工具。 |
| **API网关** | API Gateway | 位于客户端和后端服务之间的中间层,提供路由、认证、限流、日志等功能,是微服务架构的"统一大门"。 |
| **负载均衡** | Load Balancing | 将请求流量分配到多台服务器,避免单台服务器过载,提高系统可用性和性能。 |
| **SSL终结** | SSL Termination | 在网关层处理HTTPS加密解密,后端服务使用HTTP,降低后端计算开销,简化证书管理。 |
| **限流** | Rate Limiting | 限制单位时间内的请求数量,防止系统被突发流量压垮。常用算法:令牌桶、漏桶、滑动窗口。 |
| **熔断** | Circuit Breaking | 当依赖服务出现故障时,自动切断调用,防止故障扩散,并提供降级方案。 |
| **会话保持** | Session Persistence | 确保同一客户端的请求始终路由到同一台后端服务器,用于需要保持会话状态的场景。 |
| **健康检查** | Health Check | 定期检查后端服务的健康状态,自动剔除故障节点,保证流量只发送到健康的服务实例。 |
| **灰度发布** | Canary Release | 将少量流量导到新版本,验证稳定性后逐步扩大比例,降低发布风险。 |
| **WAF** | Web Application Firewall | Web应用防火墙,防护SQL注入、XSS、CC攻击等Web安全威胁。 |
| **CDN** | Content Delivery Network | 内容分发网络,在全球部署边缘节点,加速静态资源访问。 |
@@ -0,0 +1,3 @@
# 故障排查与应急响应
> 待实现
@@ -0,0 +1,3 @@
# 基础设施即代码
> 待实现
@@ -0,0 +1,3 @@
# Kubernetes 编排
> 待实现
@@ -0,0 +1,3 @@
# Linux 基础
> 待实现
@@ -0,0 +1,400 @@
# 负载均衡与网关
::: tip 🎯 核心问题
**当单台服务器扛不住时,如何把流量"聪明地"分配到多个服务器实例?** 负载均衡是现代分布式系统的"分发员"。本文通过真实案例(奶茶店收银、快递分拣、交通指挥)深入理解负载均衡的设计哲学和工程实践。
:::
---
## 1. 为什么要"负载均衡"?
### 1.1 从一个真实案例说起:某网站的架构演进
某创业公司在用户量快速增长时遇到了严重的性能问题:
**场景还原:**
```
阶段一:单台服务器
用户 → 服务器(1核2G)
日活1000 → 活跃时间:1000人同时访问
问题:CPU 100%,响应慢,经常宕机
```
::: warning ⚠️ 单台服务器的致命问题
- **性能瓶颈**: CPU 100%,响应时间> 5秒
- **单点故障**: 服务器挂了,整个网站不可用
- **扩展困难**: 只能垂直升级(加CPU、内存),贵且有限
:::
**改进后的架构(引入负载均衡):**
```
阶段二:多台服务器 + 负载均衡
用户 → 负载均衡器(Nginx)
├→ 服务器1 (1核2G)
├→ 服务器2 (1核2G)
└→ 服务器3 (1核2G)
```
::: tip ✨ 改进后的效果
- **性能提升**: 3台服务器并行处理,响应时间< 1秒
- **高可用**: 1台服务器挂了,其他服务器继续服务
- **水平扩展**: 需要更多性能?加服务器就行
:::
### 1.2 负载均衡的生活化比喻
**奶茶店收银台**
想象你开了一家网红奶茶店:
- **1个收银台**: 顾客排队,后面的人等不及,差评
- **3个收银台**: 员工分配顾客到不同收银台,效率提升3倍
**负载均衡就是"收银台分配员"**:
- **用户**(顾客) → 请求服务
- **负载均衡器**(分配员) → 把请求分配到不同服务器
- **服务器**(收银台) → 处理请求
<LoadBalancerTypesDemo />
---
## 2. 什么是负载均衡?
### 2.1 四层负载均衡(L4):只看门牌号
**工作在传输层(TCP/UDP)**,就像快递小哥只看你家的**门牌号(IP地址+端口号)**,不关心你家是做什么。
**特点:**
- **速度超快**: 只做简单的地址转发,不解析数据包内容
- **适用场景**: 数据库连接、Redis缓存、长连接游戏服务器
- **代表产品**: LVS(Linux Virtual Server)、AWS NLB、Azure Load Balancer
::: details 工作原理
```
客户端请求 → L4负载均衡器 → 后端服务器
只看IP + Port
快速转发(不解包内容)
```
:::
### 2.2 七层负载均衡(L7):检查包裹内容
**工作在应用层(HTTP/HTTPS)**,就像快递小哥不仅看门牌号,还会**打开包裹检查内容**,根据内容决定怎么送。
**特点:**
- **智能路由**: 可以根据URL路径、HTTP头、Cookie等做精细化路由
- **高级功能**: SSL卸载、内容缓存、压缩、安全WAF
- **适用场景**: Web应用、API网关、微服务架构
- **代表产品**: Nginx、HAProxy、AWS ALB、Envoy
::: details 工作原理
```
客户端请求 → L7负载均衡器 → 解析HTTP内容
检查URL、Header、Cookie
智能路由到特定服务器
```
:::
### 2.3 L4 vs L7 对比一览
| 维度 | 四层负载均衡(L4) | 七层负载均衡(L7) |
| :------------- | :------------------- | :------------------------ |
| **工作层级** | 传输层(TCP/UDP) | 应用层(HTTP/HTTPS) |
| **决策依据** | IP地址 + 端口号 | URL、Header、Cookie、Body |
| **处理速度** | 极快(内核态处理) | 较快(用户态解析) |
| **功能丰富度** | 基础转发 | SSL卸载、缓存、压缩、WAF |
| **典型场景** | 数据库、游戏、长连接 | Web应用、API网关、微服务 |
| **代表产品** | LVS、AWS NLB | Nginx、HAProxy、AWS ALB |
---
## 3. 核心问题一:如何避免"坏掉"的服务器继续接客?
### 3.1 健康检查:别让"生病"的服务器拖累系统
想象一下,你的某个收银台突然坏了,但分配员不知道,还在源源不断地把顾客分过去。结果队伍越来越长,顾客怨声载道。
**健康检查(Health Check)就是防止这种情况发生的"哨兵"**。它定期"体检"每台服务器,发现"生病"的立即从队列中移除,等"康复"了再请回来。
<!-- <HealthCheckDemo /> -->
### 3.2 主动健康检查 vs 被动健康检查
**主动健康检查(Active Health Check)**: 负载均衡器主动"敲门"问服务器"你还在吗?"
- 定期发送探测请求(如 HTTP /health、TCP ping)
- 响应超时或返回错误码则认为不健康
- **优点**: 检测结果准确可靠
- **缺点**: 产生额外的探测流量
**被动健康检查(Passive Health Check)**: 负载均衡器"观察"真实业务流量的响应情况
- 统计实际请求的响应时间、错误率
- 连续多次失败则认为不健康
- **优点**: 不产生额外流量
- **缺点**: 需要足够的流量样本才能判定
::: details 阈值设定表
| 指标 | 健康阈值 | 不健康阈值 | 说明 |
|:---|:---|:---|:---|
| **HTTP状态码** | 200-399 | 400+或超时 | 4xx/5xx都认为失败 |
| **TCP连接** | 成功建立 | 连接超时 | 检查端口是否可达 |
| **响应时间** | < 500ms | > 2000ms | 超时时间通常设为2-5秒 |
| **连续失败次数** | - | 3次 | 避免单次抖动误判 |
| **检查间隔** | - | 5s | 太频繁会增加负载 |
::: tip 💡 踸见坑:阈值设置太"敏感"
某团队将健康检查的响应时间阈值设为100ms,而他们的应用平均响应时间在80-120ms之间波动。结果是服务器频繁被标记为"不健康",导致流量在健康和不健康之间反复横跳,系统整体可用率反而下降。
**正确的做法**: 阈值应该设置为**P99响应时间的2-3倍**,给正常波动留出足够的缓冲空间。
:::
---
## 4. 核心问题二:如何保证"老顾客"一直找同一个"收银员"?
### 4.1 会话保持:让"老顾客"一直找同一个"收银员"
想象你是奶茶店的常客,每次来都由同一个店员接待。她知道你的口味偏好(半糖、去冰),服务起来又快又贴心。但如果每次来都换一个新人,你得一遍遍重复同样的要求,效率大打折扣。
**会话保持(Session Persistence/Sticky Session)** 就是解决这个问题的方法:确保同一个用户的请求,始终被路由到同一台后端服务器。
<SessionPersistenceDemo />
### 4.2 三种会话保持机制对比
| 机制 | 实现原理 | 优点 | 缺点 | 适用场景 |
| :------------- | :---------------------------------------- | :------------------------------ | :---------------------------- | :---------------------- |
| **Cookie插入** | LB在响应中插入Cookie,后续请求携带此Cookie | 不受IP变化影响,首次请求即可保持 | 客户端需支持Cookie,可能被禁用 | 电商购物车、登录态保持 |
| **IP哈希** | 对客户端IP做哈希计算,映射到特定服务器 | 无需客户端支持,无状态 | IP变化会丢失会话,难以均匀分布 | 无Cookie环境、WebSocket |
| **粘性会话表** | LB维护会话到服务器的映射表 | 支持会话复制和故障转移 | 占用LB内存,需要额外同步 | 高可用要求严格的场景 |
::: tip 💡 使用建议
- **Cookie插入**: 优先推荐,兼容性好
- **IP哈希**: 只用于WebSocket等特殊场景
- **粘性会话表**: 配合Cookie,提供故障转移能力
:::
---
## 5. 核心问题三:如何实现零停机部署?
### 5.1 蓝绿部署:"一键切换"的零停机发布
**核心思想**: 同时维护两套完全相同的生产环境(蓝环境和绿环境),但只有一个环境对外提供服务。
<BlueGreenDeploymentDemo />
**工作流程:**
1. **初始状态**: 蓝环境运行v1.0(生产),绿环境待命。
2. **部署新版本**: 在绿环境部署v1.1,进行内部冒烟测试。
3. **切换流量**: 将负载均衡器指向绿环境,流量瞬间切换到v1.1。
4. **监控观察**: 观察绿环境运行状态,确认无异常。
5. **保留旧版本**: 蓝环境保持v1.0一段时间(如24小时),作为快速回滚的保险。
::: tip ✨ 优缺点分析
| 优点 | 缺点 |
|:---|:---|
| ✅ 零停机时间,切换在毫秒级完成 | ❌ 资源成本高,需要同时维护两套环境 |
| ✅ 快速回滚,发现问题立即切回原环境 | ❌ 数据库Schema变更时需要特别处理兼容性 |
| ✅ 新环境可完整测试后再接管流量 | ❌ 不适用于有状态服务(如WebSocket长连接) |
:::
### 5.2 金丝雀发布:"小步快跑"的灰度策略
金丝雀发布得名于历史上的"煤矿金丝雀"——矿工带着金丝雀下井,如果金丝雀出现异常,说明有毒气体泄漏,矿工立即撤离。在软件发布中,金丝雀发布就是先让一小部分用户试用新版本,观察没有问题后再逐步扩大范围。
<CanaryReleaseDemo />
**核心思想:**
1. **小流量先行**: 先将1%的流量导入新版本服务器。
2. **观察指标**: 持续监控错误率、延迟、业务关键指标。
3. **逐步放量**: 如果一切正常,逐步将比例提升到5%、10%、25%、50%、100%。
4. **快速回滚**: 一旦发现异常,立即将所有流量切回旧版本。
::: tip 💡 金丝雀发布的优势
| 优势 | 说明 |
|:---|:---|
| 🎯 **风险可控** | 即使新版本有严重Bug,也只影响少量用户 |
| 📊 **真实验证** | 在真实生产环境验证,比测试环境更可靠 |
| 🚀 **快速迭代** | 团队可以更自信地频繁发布新功能 |
| 💰 **资源友好** | 不需要像蓝绿部署那样准备两套完整环境 |
:::
---
## 6. 核心问题四:如何让系统自己"呼吸"?
### 6.1 自动扩缩容:让系统像餐厅一样"灵活排班"
想象你开了一家餐厅:
- **午餐高峰期**: 需要10个服务员,但下午3点闲时只需要2个
- 如果一直维持10个\*\*: 人工成本爆炸
- 如果一直只有2个: 高峰期顾客等不及,全跑了
**自动扩缩容(Auto Scaling)** 就是让系统像餐厅一样"灵活排班"——忙的时候自动加服务器,闲的时候自动减服务器。
<AutoScalingDemo />
### 6.2 扩容指标的选择
自动扩缩容的核心是回答一个问题:\*\* **什么时候该加机器?什么时候该减机器?**
常见的决策指标:
| 指标 | 扩容阈值 | 缩容阈值 | 适用场景 |
| :------------------ | :--------- | :--------- | :--------------- |
| **CPU使用率** | > 70% | < 30% | 计算密集型应用 |
| **内存使用率** | > 75% | < 40% | 内存密集型应用 |
| **QPS(每秒请求数)** | > 1000/s | < 400/s | API网关、Web服务 |
| **连接数** | > 5000 | < 1000 | 数据库、消息队列 |
| **自定义业务指标** | 视业务而定 | 视业务而定 | 特定业务场景 |
::: tip 💡 扩容策略的"坑"与"解"
**坑1:扩容反应太慢,流量洪峰已经把系统打挂了**
某电商大促期间,设置CPU > 80%触发扩容,但监控采集有1分钟延迟,新实例启动需要3分钟。结果流量来得太快,扩容还没完成,服务器已经被打挂。
**解决方案:**
- **提前扩容**: 基于历史数据预测流量高峰,提前30分钟开始扩容
- **多级阈值**: 设置60%预警(开始预热新实例)、70%正式扩容、80%紧急扩容
- **快速扩容**: 使用容器化部署,新实例30秒内启动(相比虚拟机3-5分钟)
**坑2:扩容太激进,成本爆炸**
某创业公司设置了激进的自动扩容策略:CPU > 50%就扩容。结果一个正常的业务波动就触发了扩容,服务器数量从5台膨胀到30台,月底云账单吓哭了CTO。
**解决方案:**
- **设置扩容冷却时间**: 一次扩容后,至少等待5分钟才能再次扩容
- **设置最大实例数**: max = 当前实例数 × 2,防止无限膨胀
- **区分突刺和趋势**: 只有连续3个周期都超过阈值才扩容,避免单点突刺触发
**坑3:缩容太快,刚扩容的机器马上就缩了**
某团队设置了CPU < 30%缩容。扩容后流量还在消化,CPU短暂回落到25%,触发了缩容。刚缩完CPU又飙到80%,又触发扩容——系统在"扩容-缩容-扩容"中疯狂震荡。
**解决方案:**
- **缩容更保守**: 扩容阈值70%,缩容阈值25%,中间有足够的缓冲带
- **缩容冷却时间更长**: 扩容后至少等待10分钟才能缩容
- **渐进式缩容**: 一次只缩1台,观察后再决定要不要继续缩
:::
---
## 7. 实战:如何选择负载均衡器?
### 7.1 主流负载均衡器对比
| 特性 | Nginx | HAProxy | Envoy | 云厂商负载均衡 |
| -------------- | ------------------------------- | --------------------- | -------------- | -------------- |
| **定位** | 高性能反向代理/负载均衡 | 开源负载均衡 | 云原生代理 | 托管负载均衡 |
| **性能** | 极高(C语言,事件驱动) | 高(事件驱动) | 高(C++/Rust) | 极高 |
| **功能丰富度** | 基础负载均衡、静态文件、缓存 | 丰富的负载均衡算法 | 高级路由、观测 | 功能全面 |
| **配置** | 配置文件(nginx.conf) | 配置文件(haproxy.cfg) | API/配置文件 | UI控制台 |
| **扩展** | C模块/Lua脚本 | Lua脚本 | WASM/Filter | 插件 |
| **适用场景** | 静态资源、七层负载均衡、SSL终结 | 七层负载均衡、高可用 | 服务网格、多云 | 快速上手 |
::: tip 💡 选型建议
**决策树:**
```
选择负载均衡器:
├─ 只需要基础的四层负载均衡?
│ ├─ 是 → LVS(开源免费)或 云厂商NLB
│ └─ 否 → 继续
├─ 需要服务网格、多云部署?
│ ├─ 是 → Envoy
│ └─ 否 → 继续
├─ 需要极其复杂的配置和插件?
│ ├─ 是 → HAProxy
│ └─ 否 → 继续
├─ 需要高性能+简单配置?
│ ├─ 是 → Nginx(首选)
│ └─ 继续
├─ 想要托管运维?
│ ├─ 是 → 云厂商负载均衡(AWS ALB、阿里SLB)
│ └─ Nginx自建
```
:::
---
## 8. 总结:负载均衡的核心思维
### 8.1 核心原则回顾
| 原则 | 含义 | 实践要点 |
| -------- | -------------------------- | ------------------------------------- |
| **分层** | L4处理"快递分拣"(快但简单) | L4处理数据库、游戏;L7处理Web、API |
| **冗余** | 单点故障是架构的敌人 | 通过多实例、多区域部署提升可用性 |
| **渐进** | 发布新版本不要"一刀切" | 蓝绿部署实现零停机;金丝雀实现风险可控 |
| **弹性** | 系统应该像生命体一样"呼吸" | 忙时自动扩容,闲时自动缩容 |
### 8.2 设计检查清单
在引入负载均衡前,问自己以下问题:
- [ ] 是否真的需要负载均衡?(单机性能是否真的不够)
- [ ] 选择L4还是L7?(根据业务场景)
- [ ] 如何处理会话保持?(Cookie、IP哈希、会话表)
- [ ] 如何实现健康检查?(主动、被动、阈值设置)
- [ ] 如何实现零停机?(蓝绿部署、金丝雀)
- [ ] 如何实现弹性?(扩缩指标、冷却时间、最大实例数)
---
## 9. 名词速查表
| 名词 | 英文 | 解释 |
| ---------------- | --------------------- | ---------------------------------------- | ------------------------------ |
| **负载均衡器** | Load Balancer | 将流量分发到多个后端服务器的设备或软件 |
| **四层负载均衡** | L4 Load Balancing | 基于传输层(TCP/UDP)的负载均衡 |
| **七层负载均衡** | L7 Load Balancing | 基于应用层(HTTP/HTTPS)的负载均衡 |
| **健康检查** | Health Check | 定期检查后端服务器的健康状态的机制 |
| **会话保持** | Session Persistence | 确保同一用户的请求始终路由到同一台服务器 |
| **粘性会话** | Sticky Session | 另一种称呼,同Session Persistence |
| **蓝绿部署** | Blue-Green Deployment | 两套环境切换的零停机发布策略 |
| **金丝雀发布** | Canary Release | 小流量先行验证的灰度发布策略 |
| **自动扩缩容** | Auto Scaling | 根据负载自动增加或减少服务器数量 |
| **水平扩展** | Horizontal Scaling | 增加服务器数量来提升处理能力 |
| **垂直扩展** | Vertical Scaling | 提升单机配置(CPU、内存)来提升处理能力 |
| **多区域** | Multi-Region | 在多个地理区域部署服务 |
| **多活** | Active-Active | 多个区域同时对外提供服务 |
| **主备** | Active-Standby | 只有一个区域提供服务,其他待命 |
| **数据同步** | Data Replication | 跨区域的数据复制机制 |
| **RTO** | RTO | 恢复时间目标 | 系统故障后需要在多长时间内恢复 |
| **RPO** | RPO | 恢复点目标 | 系统故障后可以接受的数据丢失量 |
@@ -0,0 +1,639 @@
# 监控、日志与告警
> 💡 **学习指南**:本章节无需编程基础,通过交互式演示带你了解运维的完整知识体系。从监控告警到故障排查,从容量规划到自动化运维,全面掌握线上系统运维技能。
## 0. 引言:系统上线只是开始
很多新手认为:"代码部署上线,任务就完成了。"
**大错特错!**
系统上线只是**运维工作的起点**。就像买了一辆新车,后续的保养、维修、加油才是常态。
运维的目标有三个:
1. **稳定性 (Stability)**:系统不宕机,服务一直可用
2. **性能 (Performance)**:响应快速,用户体验好
3. **安全 (Security)**:数据不泄露,防止被攻击
---
## 1. 监控体系 (Monitoring)
监控是运维的"眼睛"。没有监控的系统就像盲人开车,出了问题都不知道。
### 1.1 监控的三个层次
<MonitoringDashboardDemo />
**基础设施监控**:关注服务器硬件资源
- CPU 使用率
- 内存使用率
- 磁盘空间和 I/O
- 网络带宽
**应用监控**:关注软件运行状态
- QPS(每秒请求数)
- 响应时间(延迟)
- 错误率
- 依赖服务调用情况
**业务监控**:关注业务健康度
- DAU/MAU(日活/月活)
- 订单量
- 支付成功率
- 用户留存率
### 1.2 监控工具栈
| 工具 | 用途 | 特点 |
| :------------- | :------------- | :----------------------- |
| **Prometheus** | 指标采集与存储 | 时序数据库,适合监控数据 |
| **Grafana** | 可视化面板 | 强大的图表和 dashboard |
| **Zabbix** | 综合监控 | 老牌工具,功能全面 |
| **Datadog** | SaaS 监控平台 | 一站式解决方案,收费 |
**关键点**:监控要分层,从基础设施到业务全方位覆盖,避免"盲区"。
---
## 2. 告警系统 (Alerting)
监控发现问题后,需要及时通知运维人员,这就是**告警**。
### 2.1 告警流程
<AlertFlowDemo />
### 2.2 告警级别设计
合理的告警分级能避免"告警疲劳":
| 级别 | 响应时间 | 典型场景 | 通知渠道 |
| :----- | :-------------- | :------------------------- | :----------------- |
| **P0** | 立即(5分钟内) | 核心服务宕机、支付失败 | 电话 + 短信 + 钉钉 |
| **P1** | 30分钟内 | 部分功能异常、性能严重下降 | 短信 + 钉钉 + 邮件 |
| **P2** | 当天处理 | 资源使用率偏高、偶发错误 | 钉钉 + 邮件 |
| **P3** | 本周处理 | 非核心问题、优化建议 | 邮件 |
### 2.3 告警收敛与降噪
**痛点**:一个小问题可能触发成百上千条告警,导致值班人员麻木。
**解决方案**
1. **告警分组**:相似告警合并(如同一台服务器的多个问题合并为一条)
2. **告警抑制**:如果父问题已触发,子问题不重复告警
3. **静默规则**:维护期间自动暂停告警
4. **频率限制**:同一告警短时间内不重复通知
**关键点**:告警要"少而精",每条都要值得处理。
---
## 3. 日志管理 (Logging)
日志是排查问题的"黑匣子"。
### 3.1 日志分级
```javascript
console.debug('详细调试信息') // 开发时使用
console.info('一般信息') // 正常流程记录
console.warn('警告信息') // 潜在问题
console.error('错误信息') // 需要关注的错误
```
### 3.2 结构化日志
传统日志(不好):
```
2024-01-15 10:23:45 ERROR User john failed to login, attempts=3, ip=192.168.1.100
```
结构化日志(推荐):
```json
{
"timestamp": "2024-01-15T10:23:45Z",
"level": "ERROR",
"message": "User login failed",
"user": "john",
"attempts": 3,
"ip": "192.168.1.100",
"service": "auth-service"
}
```
### 3.3 ELK 日志栈
**ELK = Elasticsearch + Logstash + Kibana**
- **Logstash**:日志采集和过滤
- **Elasticsearch**:日志存储和搜索
- **Kibana**:日志可视化查询
**最佳实践**
- ✅ 敏感信息(密码、token)不要记入日志
- ✅ 关键操作(登录、支付、权限变更)必须记录
- ✅ 日志要包含上下文(用户 ID、请求 ID、时间戳)
- ✅ 定期清理过期日志,避免磁盘爆满
---
## 4. 链路追踪 (Tracing)
在微服务架构中,一个请求可能经过十几个服务,如何追踪它的完整路径?
**Trace ID 和 Span ID**
- **Trace ID**:整个请求链路的唯一标识(像快递单号)
- **Span ID**:单个服务调用的标识(像每个中转站)
### 4.1 分布式追踪演示
<TraceVisualizationDemo />
### 4.2 OpenTelemetry 标准
OpenTelemetry (OTel) 是链路追踪的**行业标准**,提供统一的 API 和 SDK。
```javascript
// 示例:使用 OpenTelemetry 记录 Span
import { trace } from '@opentelemetry/api'
const tracer = trace.getTracer('my-service')
async function processOrder(orderId) {
// 创建一个 Span
const span = tracer.startSpan('processOrder')
try {
// 设置属性
span.setAttribute('order.id', orderId)
// 业务逻辑...
await validateOrder(orderId)
await saveToDatabase(orderId)
span.setStatus({ code: SpanStatusCode.OK })
} catch (error) {
span.recordException(error)
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
} finally {
span.end() // 结束 Span
}
}
```
**关键点**:链路追踪能快速定位性能瓶颈和故障点,是微服务必备工具。
---
## 5. 故障排查流程
线上故障不可避免,关键是**快速响应、快速恢复**。
### 5.1 故障处理流程
<IncidentResponseDemo />
### 5.2 常用排查工具
| 工具 | 用途 | 典型场景 |
| :----------- | :----------- | :----------------------- |
| **tcpdump** | 抓包分析 | 网络不通、数据包丢失 |
| **strace** | 追踪系统调用 | 进程卡住、文件权限问题 |
| **Arthas** | Java 诊断 | CPU 飙高、内存泄漏、死锁 |
| **top/htop** | 系统资源监控 | CPU/内存占用高 |
| **netstat** | 网络连接查看 | 端口占用、连接数异常 |
| **lsof** | 查看打开文件 | 文件被占用、磁盘满 |
**Arthas 示例**(阿里开源的 Java 诊断工具):
```bash
# 查看 CPU 最高的前 5 个线程
$ top -H -p 12345
# 查看某个方法的调用耗时
$ trace com.example.OrderService createOrder
# 查看类的静态字段
$ getstatic com.example.Config MAX_CONNECTIONS
# 热更新代码(无需重启)
$ mc /tmp/Test.java
$ redefine /tmp/Test.class
```
### 5.3 故障复盘 (Post-mortem)
**复盘不是追责会!**
复盘的目的是:
1. 梳理故障时间线
2. 找出根本原因 (Root Cause Analysis)
3. 总结经验教训
4. 制定改进措施
**5 Why 分析法**
问"为什么"至少 5 次,找到根本原因:
- 为什么服务宕机?
- 因为内存溢出
- 为什么内存溢出?
- 因为缓存数据过多
- 为什么缓存数据过多?
- 因为没有设置过期时间
- 为什么没有设置过期时间?
- 因为开发时遗漏了
- **根本原因**:缺少代码审查和测试用例
**关键点**:建立 blameless 文化,关注流程改进而非个人责任。
---
## 6. 性能优化
### 6.1 性能瓶颈分析
**从上到下的优化思路**
```
用户感知
前端优化(减少请求、CDN、懒加载)
网络优化(HTTP/2、压缩、长连接)
后端优化(缓存、异步、批处理)
数据库优化(索引、查询优化、分库分表)
系统优化(内核参数、JVM 调优)
```
### 6.2 数据库优化
**索引优化**
```sql
-- 查询慢(无索引)
SELECT * FROM orders WHERE user_id = 12345;
-- 创建索引后快 100 倍
CREATE INDEX idx_user_id ON orders(user_id);
```
**查询优化**
```sql
-- ❌ 避免 SELECT *
SELECT * FROM users WHERE id = 123;
-- ✅ 只查需要的字段
SELECT id, name, email FROM users WHERE id = 123;
-- ❌ 避免 IN 子句太多
SELECT * FROM orders WHERE user_id IN (1, 2, 3, ..., 10000);
-- ✅ 使用 JOIN 或批量查询
SELECT * FROM orders o JOIN user_ids u ON o.user_id = u.id;
```
### 6.3 缓存优化
**多级缓存架构**
```
浏览器缓存 (CDN)
本地缓存 (内存/Guava)
分布式缓存 (Redis/Memcached)
数据库 (MySQL/PostgreSQL)
```
**缓存更新策略**
| 策略 | 优点 | 缺点 | 适用场景 |
| :---------------- | :----------- | :----------- | :----------------------- |
| **Cache-Aside** | 简单、可靠 | 首次查询慢 | 读多写少 |
| **Write-Through** | 数据一致性好 | 写入慢 | 读写均衡 |
| **Write-Behind** | 写入极快 | 可能丢失数据 | 写多读少、允许短时不一致 |
**关键点**:缓存不是银弹,要考虑一致性、雪崩、穿透等问题(参考《系统缓存设计》章节)。
---
## 7. 容量规划
### 7.1 容量评估
<CapacityPlanningDemo />
### 7.2 压力测试
**工具选择**
| 工具 | 特点 | 适用场景 |
| :--------- | :------------------ | :------------ |
| **JMeter** | 功能强大、可视化 | HTTP 接口压测 |
| **wrk/ab** | 轻量、命令行 | 快速基准测试 |
| **Locust** | Python 脚本、分布式 | 复杂场景压测 |
| **K6** | 现代、JS 脚本 | CI/CD 集成 |
**wrk 示例**
```bash
# 安装 wrk
$ brew install wrk # macOS
$ apt install wrk # Ubuntu
# 压测 HTTP 接口(10 线程,持续 30 秒)
$ wrk -t10 -c100 -d30s http://example.com/api/users
# 输出:
# Running 30s test @ http://example.com/api/users
# 10 threads and 100 connections
# Thread Stats Avg Stdev Max +/- Stdev
# Latency 45.32ms 12.45ms 120.50ms 87.56%
# Req/Sec 2.12k 123.45 3.45k 89.01%
# 632450 requests in 30.00s, 1.23GB read
# Requests/sec: 21081.67
```
### 7.3 弹性扩缩容
**云原生时代的自动扩缩容**
```yaml
# Kubernetes HPA (Horizontal Pod Autoscaler)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
```
**当 CPU 使用率超过 70% 时,自动扩容 Pod(最多 10 个)**
**关键点**:结合业务预测(如双 11)提前扩容,避免来不及。
---
## 8. 安全运维
### 8.1 访问控制
**最小权限原则**
- 开发人员只能访问开发环境
- 运维人员只能访问生产环境,且需要审批
- 数据库敏感操作需要二次确认
**堡垒机 (Jump Server)**
所有运维操作通过堡垒机进行,记录完整操作日志。
### 8.2 数据备份
**3-2-1 备份原则**
- **3**份数据副本(1 份原始 + 2 份备份)
- **2**种不同存储介质(本地磁盘 + 云存储)
- **1**份异地备份(防止单点灾难)
**备份策略**
| 类型 | 频率 | 保留时间 | RTO | RPO |
| :----------- | :--- | :------- | :----- | :------ |
| **全量备份** | 每周 | 1 个月 | 4 小时 | 24 小时 |
| **增量备份** | 每天 | 1 周 | 2 小时 | 1 小时 |
| **实时备份** | 秒级 | 7 天 | 分钟级 | 秒级 |
**RTO (Recovery Time Objective)**:恢复时间目标(服务最多中断多久)
**RPO (Recovery Point Objective)**:恢复点目标(最多丢失多少数据)
### 8.3 漏洞扫描
**定期扫描**
- **代码扫描**SonarQube、ESLint(发现潜在漏洞)
- **依赖扫描**npm audit、Snyk(检测第三方库漏洞)
- **容器扫描**:Trivy、Clair(检测镜像漏洞)
```bash
# npm audit 示例
$ npm audit
found 3 vulnerabilities (1 moderate, 2 high)
Package Severity Vulnerable versions
lodash high <4.17.21
express moderate 4.0.0 - 4.18.2
# 自动修复
$ npm audit fix
```
---
## 9. 自动化运维 (DevOps)
### 9.1 CI/CD 流水线
```yaml
# .gitlab-ci.yml 示例
stages:
- test
- build
- deploy
test:
stage: test
script:
- npm install
- npm test
tags:
- docker
build:
stage: build
script:
- docker build -t myapp:$CI_COMMIT_SHA .
- docker push registry.example.com/myapp:$CI_COMMIT_SHA
only:
- main
deploy:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=registry.example.com/myapp:$CI_COMMIT_SHA
environment:
name: production
when: manual # 手动触发部署
```
### 9.2 基础设施即代码 (IaC)
**Terraform 示例**(管理云资源):
```hcl
# main.tf
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
Env = "production"
}
}
resource "aws_security_group" "web" {
name = "web-sg"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
```
**优势**
- ✅ 版本控制:所有配置在 Git 中
- ✅ 可重复:环境一致性
- ✅ 可审计:变更历史清晰
- ✅ 可回滚:快速恢复到之前版本
### 9.3 GitOps 实践
**GitOps = Git + IaC + Automation**
核心理念:**Git 仓库是基础设施的唯一真实来源**
工作流程:
```
1. 修改配置文件(push 到 Git
2. Git 仓库变更触发 CI/CD
3. 自动执行terraform apply/kubectl apply
4. 基础设施自动更新
5. 监控对比实际状态与期望状态
```
**工具**ArgoCD、FluxKubernetes 部署)
---
## 10. 总结与最佳实践
运维是一个庞大的体系,但核心可以概括为:
### 10.1 运维成熟度模型
| 等级 | 特征 | 实践 |
| :------- | :----------------- | :----------------------------- |
| **初级** | 被动响应,人工操作 | 出问题才处理,手工部署 |
| **中级** | 自动化,标准化 | CI/CD、监控告警、文档化 |
| **高级** | 预防为主,自愈 | 容量规划、故障演练、自动扩缩容 |
| **专家** | 智能化,无人值守 | AIOps、混沌工程、Serverless |
### 10.2 运维工程师的一天
```
09:00 - 查看夜间告警,确认系统状态
10:00 - 处理用户反馈的问题
11:00 - 参加研发周会,评估新方案运维风险
14:00 - 优化慢查询,提升性能
15:00 - 代码审查(Code Review
16:00 - 编写部署文档,更新监控规则
17:00 - 故障演练(Chaos Engineering
18:00 - 值班交接
```
### 10.3 学习路线
**入门阶段**1-3 个月):
- 学会 Linux 常用命令
- 了解监控系统(Prometheus + Grafana
- 掌握日志查询(ELK
**进阶阶段**3-6 个月):
- 深入理解容器技术(Docker + K8s
- 掌握一门诊断工具(Arthas、tcpdump
- 实践 CI/CD 流水线
**高级阶段**6-12 个月):
- 性能调优(数据库、JVM、网络)
- 容量规划与成本优化
- 故障复盘与流程改进
**专家阶段**1 年以上):
- 架构设计(高可用、容灾)
- 混沌工程(主动注入故障)
- AIOps(智能运维)
---
## 11. 名词速查表 (Glossary)
| 名词 | 全称 | 解释 |
| :-------------- | :-------------------------------- | :--------------------------------------------- |
| **Monitoring** | - | 监控,实时观测系统运行状态。 |
| **Alerting** | - | 告警,异常时通知相关人员。 |
| **Logging** | - | 日志,记录系统运行过程中的事件。 |
| **Tracing** | - | 链路追踪,跟踪请求在分布式系统中的完整路径。 |
| **QPS** | Queries Per Second | 每秒请求数,衡量系统吞吐量。 |
| **Latency** | - | 延迟,请求从发出到响应的时间。 |
| **RTO** | Recovery Time Objective | 恢复时间目标,服务最多中断多久。 |
| **RPO** | Recovery Point Objective | 恢复点目标,最多丢失多少数据。 |
| **Post-mortem** | - | 故障复盘,分析故障原因和改进措施。 |
| **CI/CD** | Continuous Integration/Delivery | 持续集成与持续交付,自动化测试与部署。 |
| **IaC** | Infrastructure as Code | 基础设施即代码,用代码管理服务器、网络等资源。 |
| **GitOps** | - | Git 运维,Git 仓库是基础设施的唯一真实来源。 |
| **ELK** | Elasticsearch + Logstash + Kibana | 日志采集、存储、可视化三件套。 |
| **SLA** | Service Level Agreement | 服务等级协议,承诺的服务可用性(如 99.9%)。 |
| **Blameless** | - | 无责备文化,复盘关注流程改进而非个人责任。 |
---
## 12. 延伸阅读
- **[系统缓存设计](/zh-cn/appendix/cache-design)** - 缓存原理、模式与最佳实践
- **[消息队列设计](/zh-cn/appendix/queue-design)** - 削峰填谷、异步解耦
- **[鉴权原理与实战](/zh-cn/appendix/auth-design)** - 认证授权、安全加固
- **[后端进化史](/zh-cn/appendix/backend-evolution)** - 从单体到微服务到 Serverless
- **[部署与上线](/zh-cn/appendix/deployment)** - 从开发到生产的最后一公里