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:
@@ -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`(管理员账号)。
|
||||
- **登录密码**:初始密码,或者是让你设置密码的链接。
|
||||
|
||||
有了这些信息,就可以用 **SSH(Secure 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:"hey,my-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)。
|
||||
|
||||
**HTTP(HyperText Transfer Protocol)** 是用来传输网页的协议。可以把它理解成运输数据的卡车。但这辆卡车是**透明的**。里面装的东西所有人都能看见。在 HTTP 网站上输入的密码、填写的个人信息。在传输过程中可能被中间的任何人偷看到。
|
||||
|
||||
**HTTPS(HTTP 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 一家的。
|
||||
- **ELK(Elasticsearch + 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 />
|
||||
|
||||
面对这些挑战,单纯依靠"小心点操作"已经行不通了。我们需要一套系统的权限管理方法论,这正是**IAM(Identity and Access Management,身份与访问管理)**试图解决的问题。
|
||||
|
||||
---
|
||||
|
||||
## 1. 什么是 IAM/RAM?从"门禁系统"说起
|
||||
|
||||
### 1.1 类比:公司的智能门禁
|
||||
|
||||
想象一下,你们公司搬到了一栋新写字楼:
|
||||
|
||||
| 场景 | 没有 IAM 的做法 | 有 IAM 的做法 |
|
||||
| :--------- | :----------------------------- | :------------------------------------------- |
|
||||
| 新员工入职 | 给他一把能开所有门的万能钥匙 | 给他一张门禁卡,只能刷他办公区域的门 |
|
||||
| 员工离职 | 钥匙丢了就丢了,也不知道谁拿着 | 立即在系统里注销他的门禁卡,所有门都打不开了 |
|
||||
| 外包人员 | 把钥匙借给他几天 | 发临时门禁卡,设置3天后自动失效 |
|
||||
| 访客 | 前台配一把钥匙给他 | 发一次性访客码,只能进会议室 |
|
||||
|
||||
**IAM(Identity 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 Federation(OpenID 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 />
|
||||
|
||||
MFA(Multi-Factor Authentication,多因素认证),也叫 2FA(Two-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 的原理
|
||||
|
||||
```
|
||||
账号 A(Production) 账号 B(Shared 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 Role(EC2 用)
|
||||
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(必须)
|
||||
- 推荐硬件 MFA(YubiKey),或者 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
|
||||
|
||||
在全球云服务市场,有三家厂商占据了主导地位。
|
||||
|
||||
**AWS(Amazon 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、Flux(Kubernetes 部署)
|
||||
|
||||
---
|
||||
|
||||
## 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)** - 从开发到生产的最后一公里
|
||||
Reference in New Issue
Block a user