08 - 实战应用场景¶
本章核心: 通过真实项目案例,综合运用所学网络知识解决实际问题
📖 章节导航¶
前序章节: 06-云服务与CDN.md → 07-Docker网络.md 后续章节: 09-AI网络专题.md 快速参考: 网络工具箱.md 全部章节 故障排查: 故障排查手册.md 第4章
📚 目录¶
🎓 引言¶
为什么要学习实战应用?¶
理论知识是基础,但只有通过实际项目才能真正理解和掌握网络技术。本章节将通过5个真实场景,带你从零开始完成完整的网络项目部署。
学习目标¶
✅ 掌握从购买服务器到部署应用的完整流程 ✅ 理解DNS、HTTPS、CDN等技术的实际应用 ✅ 学会配置代理和科学上网环境 ✅ 掌握Docker网络和容器化部署 ✅ 培养网络故障排查能力
前置知识¶
在学习本章之前,建议你已经掌握了: - 基本的Linux命令操作 - 前面章节的网络基础知识 - Docker的基本使用 - 基本的编程能力
🌐 实战案例一:搭建个人博客网站¶
📋 场景描述¶
搭建一个现代化的个人博客网站,支持HTTPS访问,使用CDN加速静态资源,具备良好的性能和安全性。
🛠️ 技术栈¶
- 前端:Next.js + React
- 容器化:Docker + Docker Compose
- Web服务器:Nginx
- HTTPS:Let's Encrypt + Certbot
- CDN:阿里云CDN
- 域名:从域名注册商购买
第一步:购买域名和服务器¶
1.1 购买域名¶
推荐域名注册商: - 阿里云:https://wanwang.aliyun.com - 腾讯云:https://dnspod.cloud.tencent.com - Namecheap:https://www.namecheap.com
购买步骤:
域名选择建议: - ✅ 选择.com、.cn等常见后缀 - ✅ 域名简短易记 - ✅ 避免使用特殊字符 - ❌ 避免使用商标名称
1.2 购买服务器¶
推荐云服务商: - 阿里云:https://www.aliyun.com - 腾讯云:https://cloud.tencent.com - 华为云:https://www.huaweicloud.com
服务器配置建议:
购买步骤:
# 登录云服务商控制台
# 选择"云服务器ECS" → "创建实例"
# 选择地域(建议选择离用户近的地域)
# 选择实例规格(2核4GB)
# 选择镜像(Ubuntu 20.04 LTS)
# 选择存储(40GB SSD)
# 选择带宽(3Mbps)
# 设置登录密码(记住这个密码!)
# 确认订单并支付
第二步:配置DNS解析¶
2.1 获取服务器公网IP¶
登录云服务器控制台,找到服务器的公网IP地址,例如:47.95.123.45
2.2 配置DNS解析记录¶
在域名注册商的DNS管理页面,添加以下记录:
记录类型:A
主机记录:@
记录值:47.95.123.45
TTL:600
记录类型:A
主机记录:www
记录值:47.95.123.45
TTL:600
记录类型:CNAME
主机记录:cdn
记录值:your-cdn-domain.com
TTL:600
DNS解析说明: - @ 表示根域名,访问 myblog.com 会解析到服务器IP - www 表示子域名,访问 www.myblog.com 会解析到服务器IP - cdn 表示CDN域名,用于加速静态资源
2.3 验证DNS解析¶
第三步:使用SSH连接服务器¶
3.1 获取服务器信息¶
从云服务商控制台获取: - 公网IP:47.95.123.45 - 用户名:root(Ubuntu默认) - 密码:购买时设置的密码
3.2 使用SSH连接¶
Windows用户:
Mac/Linux用户:
配置SSH密钥登录(推荐):
# 在本地电脑生成SSH密钥对
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 将公钥复制到服务器
ssh-copy-id root@47.95.123.45
# 现在可以免密登录
ssh root@47.95.123.45
3.3 优化SSH配置¶
# 编辑SSH配置文件
sudo nano /etc/ssh/sshd_config
# 修改以下配置:
Port 2222 # 修改默认端口,提高安全性
PermitRootLogin no # 禁止root直接登录
PasswordAuthentication no # 禁用密码登录
PubkeyAuthentication yes # 启用密钥登录
# 重启SSH服务
sudo systemctl restart sshd
第四步:部署Web应用(使用Docker)¶
4.1 安装Docker和Docker Compose¶
# 更新系统包
sudo apt update && sudo apt upgrade -y
# 安装Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker
# 安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker --version
docker-compose --version
4.2 创建项目目录结构¶
4.3 创建Docker Compose配置文件¶
创建 docker-compose.yml:
version: '3.8'
services:
# Next.js应用容器
app:
image: node:18-alpine
working_dir: /app
volumes:
- ./app:/app
- /app/node_modules
- /app/.next
ports:
- "3000:3000"
command: npm start
restart: unless-stopped
environment:
- NODE_ENV=production
# Nginx反向代理
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- ./app/public:/usr/share/nginx/html:ro
depends_on:
- app
restart: unless-stopped
4.4 创建Nginx配置文件¶
创建 nginx/nginx.conf:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss;
# HTTP重定向到HTTPS
server {
listen 80;
server_name myblog.com www.myblog.com;
return 301 https://$server_name$request_uri;
}
# HTTPS配置
server {
listen 443 ssl http2;
server_name myblog.com www.myblog.com;
# SSL证书配置(稍后配置)
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# SSL优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 静态资源
location /static/ {
alias /usr/share/nginx/html/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# API代理
location /api/ {
proxy_pass http://app:3000/api/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Next.js应用
location / {
proxy_pass http://app:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
4.5 创建简单的Next.js应用¶
# 进入app目录
cd ~/myblog/app
# 初始化Next.js项目
npx create-next-app@latest . --typescript --tailwind --eslint
# 创建简单的首页
cat > pages/index.tsx << 'EOF'
import Head from 'next/head'
import styles from '../styles/Home.module.css'
export default function Home() {
return (
<>
<Head>
<title>我的个人博客</title>
<meta name="description" content="欢迎来到我的个人博客" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>
欢迎来到我的个人博客 🎉
</h1>
<p className={styles.description}>
这是一个使用Next.js + Docker + Nginx搭建的现代化博客网站
</p>
<div className={styles.grid}>
<a href="/about" className={styles.card}>
<h2>关于我 →</h2>
<p>了解更多关于我的信息</p>
</a>
<a href="/blog" className={styles.card}>
<h2>博客文章 →</h2>
<p>阅读我的技术文章</p>
</a>
</div>
</main>
</>
)
}
EOF
4.6 启动服务¶
# 回到项目根目录
cd ~/myblog
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
第五步:配置HTTPS证书¶
5.1 安装Certbot¶
# 安装Certbot
sudo apt install certbot -y
# 安装Certbot Nginx插件
sudo apt install python3-certbot-nginx -y
5.2 获取SSL证书¶
# 获取证书(自动配置Nginx)
sudo certbot --nginx -d myblog.com -d www.myblog.com
# 按提示操作:
# 1. 输入邮箱地址
# 2. 同意服务条款
# 3. 选择是否分享邮箱
# 4. 选择是否将HTTP重定向到HTTPS(选择2)
5.3 自动续期证书¶
# 测试自动续期
sudo certbot renew --dry-run
# Certbot会自动创建定时任务
# 查看定时任务
sudo systemctl list-timers | grep certbot
5.4 手动配置证书(可选)¶
如果自动配置失败,可以手动配置:
# 停止Nginx容器
docker-compose stop nginx
# 获取证书
sudo certbot certonly --standalone -d myblog.com -d www.myblog.com
# 复制证书到项目目录
sudo cp /etc/letsencrypt/live/myblog.com/fullchain.pem ~/myblog/nginx/ssl/
sudo cp /etc/letsencrypt/live/myblog.com/privkey.pem ~/myblog/nginx/ssl/
# 设置权限
sudo chmod 644 ~/myblog/nginx/ssl/*.pem
# 重启Nginx
docker-compose start nginx
第六步:使用CDN加速静态资源¶
6.1 开通CDN服务¶
登录阿里云/腾讯云控制台: 1. 选择"CDN"服务 2. 点击"添加域名" 3. 输入域名:cdn.myblog.com 4. 选择业务类型:图片小文件 5. 配置源站信息: - 源站类型:IP源站 - 源站地址:47.95.123.45 - 端口:80 6. 点击"确定"
6.2 配置CDN加速规则¶
在CDN控制台配置缓存规则:
文件类型:.js;.css;.png;.jpg;.jpeg;.gif;.ico;.svg;.woff;.woff2
缓存时间:30天
文件类型:.html;.json
缓存时间:1小时
文件类型:*
缓存时间:不缓存
6.3 配置HTTPS(CDN)¶
在CDN控制台配置HTTPS: 1. 选择"HTTPS配置" 2. 开启HTTPS 3. 选择证书类型:免费证书或上传已有证书 4. 开启HTTP/2 5. 开启强制HTTPS
6.4 修改应用使用CDN¶
在Next.js应用中配置CDN:
// next.config.js
module.exports = {
assetPrefix: process.env.NODE_ENV === 'production'
? 'https://cdn.myblog.com'
: '',
images: {
domains: ['cdn.myblog.com'],
},
}
// 在组件中使用CDN
const Image = ({ src, alt }) => { // 箭头函数:简洁的函数语法
const cdnUrl = process.env.NODE_ENV === 'production' // const不可重新赋值;let块级作用域变量
? `https://cdn.myblog.com${src}`
: src
return <img src={cdnUrl} alt={alt} />
}
6.5 测试CDN加速¶
# 查看CDN状态
curl -I https://cdn.myblog.com/static/logo.png
# 查看响应头中的CDN信息
# X-Cache: HIT from cdn-node-xxx # 命中缓存
# X-Cache: MISS from cdn-node-xxx # 未命中缓存
📊 项目总结¶
完成的功能: ✅ 域名购买和DNS解析 ✅ 服务器配置和SSH连接 ✅ Docker容器化部署 ✅ Nginx反向代理和负载均衡 ✅ HTTPS证书自动续期 ✅ CDN加速静态资源
技术要点: - DNS解析将域名映射到服务器IP - SSH提供安全的远程连接 - Docker实现应用容器化部署 - Nginx作为反向代理处理HTTP请求 - HTTPS加密保护数据传输安全 - CDN加速静态资源,提升访问速度
🚀 实战案例二:配置科学上网环境¶
📋 场景描述¶
配置一个稳定的科学上网环境,访问Google、GitHub等被墙网站,使用Clash客户端和TUN模式实现全局代理。
🛠️ 技术栈¶
- VPS服务器:购买海外VPS
- 代理服务端:V2Ray / Xray
- 客户端:Clash for Windows / ClashX
- 代理模式:TUN模式(全局代理)
- 规则:PAC规则(智能分流)
第一步:购买VPS服务器¶
1.1 选择VPS服务商¶
推荐VPS服务商: - DigitalOcean:https://www.digitalocean.com - Vultr:https://www.vultr.com - Linode:https://www.linode.com - BandwagonHost:https://bwh81.net
服务器配置建议:
1.2 购买步骤¶
1. 注册账号并充值
2. 选择服务器地域(推荐:美国、日本、新加坡)
3. 选择服务器配置
4. 选择操作系统(Ubuntu 20.04 LTS)
5. 创建服务器
6. 记录服务器IP和密码
第二步:安装代理服务端¶
2.1 连接到VPS¶
# 使用SSH连接
ssh root@your-vps-ip
# 输入密码
# 更新系统
apt update && apt upgrade -y # &&前一个成功才执行后一个;||前一个失败才执行
2.2 安装V2Ray服务端¶
# 下载并安装V2Ray
bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)
# 启动V2Ray
systemctl start v2ray
systemctl enable v2ray
# 查看状态
systemctl status v2ray
2.3 配置V2Ray¶
# 备份原配置
cp /usr/local/etc/v2ray/config.json /usr/local/etc/v2ray/config.json.bak
# 创建新配置
cat > /usr/local/etc/v2ray/config.json << 'EOF'
{
"log": {
"access": "/var/log/v2ray/access.log",
"error": "/var/log/v2ray/error.log",
"loglevel": "warning"
},
"inbounds": [
{
"port": 10086,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "your-uuid-here",
"alterId": 0
}
]
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/ray"
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"settings": {}
}
]
}
EOF
# 生成UUID
cat /proc/sys/kernel/random/uuid
# 将生成的UUID替换配置文件中的"your-uuid-here"
# 重启V2Ray
systemctl restart v2ray
2.4 配置Nginx反向代理(可选)¶
为了隐藏V2Ray流量,可以使用Nginx作为反向代理:
# 安装Nginx
apt install nginx -y
# 创建Nginx配置
cat > /etc/nginx/sites-available/v2ray << 'EOF'
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/your/cert.pem;
ssl_certificate_key /path/to/your/key.pem;
location /ray {
proxy_pass http://127.0.0.1:10086;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
}
}
EOF
# 启用配置
ln -s /etc/nginx/sites-available/v2ray /etc/nginx/sites-enabled/
# 测试配置
nginx -t
# 重启Nginx
systemctl restart nginx
第三步:配置Clash客户端¶
3.1 下载Clash客户端¶
Windows用户: - 下载:https://github.com/Fndroid/clash_for_windows_pkg/releases - 安装:解压后运行 Clash for Windows.exe
Mac用户: - 下载:https://github.com/yichengchen/clashX/releases - 安装:拖拽到应用程序文件夹
3.2 创建Clash配置文件¶
创建 config.yaml:
# Clash配置文件
port: 7890
socks-port: 7891
allow-lan: true
mode: Rule
log-level: info
external-controller: 127.0.0.1:9090
proxies:
- name: "VPS-VMess"
type: vmess
server: your-vps-ip
port: 443
uuid: your-uuid-here
alterId: 0
cipher: auto
udp: true
network: ws
ws-path: /ray
tls: true
proxy-groups:
- name: "🚀 节点选择"
type: select
proxies:
- VPS-VMess
- DIRECT
- name: "🎯 全球直连"
type: select
proxies:
- DIRECT
- 🚀 节点选择
- name: "🛑 全球拦截"
type: select
proxies:
- REJECT
- DIRECT
- name: "🍃 应用净化"
type: select
proxies:
- REJECT
- DIRECT
- name: "🐟 漏网之鱼"
type: select
proxies:
- 🚀 节点选择
- 🎯 全球直连
- 🛑 全球拦截
rules:
# 局域网网络
- GEOIP,CN,DIRECT
# 拦截广告
- DOMAIN-SUFFIX,ad.com,🛑 全球拦截
- DOMAIN-KEYWORD,ad,🛑 全球拦截
# 常见网站直连
- DOMAIN-SUFFIX,cn,DIRECT
- DOMAIN-KEYWORD,baidu,DIRECT
- DOMAIN-KEYWORD,taobao,DIRECT
- DOMAIN-KEYWORD,alipay,DIRECT
- DOMAIN-KEYWORD,weixin,DIRECT
# Google服务
- DOMAIN-SUFFIX,google.com,🚀 节点选择
- DOMAIN-SUFFIX,googleapis.com,🚀 节点选择
- DOMAIN-SUFFIX,gstatic.com,🚀 节点选择
# GitHub
- DOMAIN-SUFFIX,github.com,🚀 节点选择
- DOMAIN-SUFFIX,githubusercontent.com,🚀 节点选择
# YouTube
- DOMAIN-SUFFIX,youtube.com,🚀 节点选择
- DOMAIN-SUFFIX,googlevideo.com,🚀 节点选择
# Netflix
- DOMAIN-SUFFIX,netflix.com,🚀 节点选择
# 其他国外网站
- GEOIP,US,🚀 节点选择
- MATCH,🐟 漏网之鱼
3.3 导入配置文件¶
Clash for Windows: 1. 打开Clash for Windows 2. 点击"Profiles" → "Import" 3. 选择 config.yaml 文件 4. 点击"Select"选择配置 5. 开启"System Proxy"
ClashX: 1. 打开ClashX 2. 点击菜单栏图标 3. 选择"配置" → "导入配置文件" 4. 选择 config.yaml 文件 5. 开启"系统代理"
第四步:配置TUN模式¶
4.1 什么是TUN模式?¶
TUN模式(Tun模式)是一种虚拟网络设备模式,可以在系统层面创建一个虚拟网卡,所有流量都会经过这个虚拟网卡,从而实现全局代理。
4.2 配置TUN模式¶
Clash for Windows: 1. 打开Clash for Windows 2. 点击"Settings" → "Tun Mode" 3. 开启"Enable" 4. 设置"Stack"为"system" 5. 设置"Auto Route"为"true" 6. 设置"Auto Detect Interface"为"true" 7. 重启Clash
ClashX Pro: 1. 打开ClashX Pro 2. 点击菜单栏图标 3. 选择"增强模式" → "开启" 4. 输入系统密码
4.3 验证TUN模式¶
# 查看虚拟网卡
# Windows: ipconfig
# Mac: ifconfig
# 测试代理是否生效
curl -I https://www.google.com
curl -I https://www.github.com
# 查看IP地址
curl https://api.ipify.org
# 应该返回VPS的IP地址
第五步:配置PAC规则¶
5.1 什么是PAC规则?¶
PAC(Proxy Auto-Config)规则是一种自动代理配置脚本,可以根据访问的域名自动判断是否使用代理。
5.2 创建PAC规则文件¶
创建 pac.txt:
function FindProxyForURL(url, host) {
// 局域网直连
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")) {
return "DIRECT";
}
// 常见国内网站直连
if (dnsDomainIs(host, ".cn") ||
dnsDomainIs(host, ".baidu.com") ||
dnsDomainIs(host, ".taobao.com") ||
dnsDomainIs(host, ".alipay.com") ||
dnsDomainIs(host, ".weixin.com") ||
dnsDomainIs(host, ".qq.com")) {
return "DIRECT";
}
// Google服务
if (dnsDomainIs(host, ".google.com") ||
dnsDomainIs(host, ".googleapis.com") ||
dnsDomainIs(host, ".gstatic.com")) {
return "PROXY 127.0.0.1:7890";
}
// GitHub
if (dnsDomainIs(host, ".github.com") ||
dnsDomainIs(host, ".githubusercontent.com")) {
return "PROXY 127.0.0.1:7890";
}
// YouTube
if (dnsDomainIs(host, ".youtube.com") ||
dnsDomainIs(host, ".googlevideo.com")) {
return "PROXY 127.0.0.1:7890";
}
// 其他国外网站
return "PROXY 127.0.0.1:7890";
}
5.3 使用PAC规则¶
Clash for Windows: 1. 打开Clash for Windows 2. 点击"Settings" → "Allow LAN" 3. 设置"PAC File"路径 4. 在浏览器中配置PAC: - Chrome: 设置 → 系统 → 打开代理设置 - 选择"自动配置脚本" - 输入:http://127.0.0.1:9090/pac
第六步:测试代理是否生效¶
6.1 测试基本连接¶
# 测试Google
curl -I https://www.google.com
# 测试GitHub
curl -I https://github.com
# 测试YouTube
curl -I https://www.youtube.com
# 查看当前IP
curl https://api.ipify.org
6.2 测试速度¶
# 测试下载速度
curl -o /dev/null https://speed.hetzner.de/100MB.bin
# 使用speedtest-cli
pip install speedtest-cli
speedtest-cli
6.3 测试DNS解析¶
6.4 测试浏览器访问¶
- 打开浏览器
- 访问 https://www.google.com
- 访问 https://github.com
- 访问 https://www.youtube.com
- 检查是否能正常访问
📊 项目总结¶
完成的功能: ✅ 购买海外VPS服务器 ✅ 安装配置V2Ray服务端 ✅ 配置Clash客户端 ✅ 配置TUN模式实现全局代理 ✅ 配置PAC规则实现智能分流 ✅ 测试代理功能
技术要点: - V2Ray提供稳定的代理服务 - Clash客户端支持多种代理协议 - TUN模式实现全局代理 - PAC规则实现智能分流 - DNS解析和流量转发 - 加密传输保护隐私
🤖 实战案例三:部署AI模型API服务¶
📋 场景描述¶
部署一个AI模型API服务,提供模型推理能力,使用Docker容器化部署,配置Nginx反向代理,使用CDN加速访问,使用OSS存储模型文件。
🛠️ 技术栈¶
- AI框架:PyTorch / TensorFlow
- API框架:FastAPI
- 容器化:Docker + Docker Compose
- Web服务器:Nginx
- 存储:阿里云OSS
- CDN:阿里云CDN
- 监控:Prometheus + Grafana
第一步:使用Docker打包模型服务¶
1.1 创建项目结构¶
# 创建项目目录
mkdir -p ~/ai-api-service
cd ~/ai-api-service
# 创建必要的目录
mkdir -p app/models
mkdir -p app/api
mkdir -p nginx
mkdir -p prometheus
mkdir -p grafana
1.2 创建Dockerfile¶
创建 Dockerfile:
# 使用Python官方镜像
FROM python:3.10-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY app/ ./app/
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
1.3 创建requirements.txt¶
创建 requirements.txt:
fastapi==0.104.1
uvicorn[standard]==0.24.0
pydantic==2.5.0
torch==2.1.0
transformers==4.35.0
numpy==1.24.3
pillow==10.1.0
python-multipart==0.0.6
aiofiles==23.2.1
prometheus-client==0.19.0
oss2==2.18.4
1.4 创建FastAPI应用¶
创建 app/main.py:
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import uvicorn
import torch
from transformers import pipeline
from prometheus_client import Counter, Histogram, generate_latest
from fastapi.responses import Response
import time
# 创建FastAPI应用
app = FastAPI(
title="AI Model API Service",
description="AI模型推理API服务",
version="1.0.0"
)
# 配置CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Prometheus指标
request_counter = Counter('api_requests_total', 'Total API requests', ['endpoint', 'method'])
request_duration = Histogram('api_request_duration_seconds', 'API request duration', ['endpoint'])
# 加载模型
print("Loading AI models...")
classifier = pipeline("text-classification", model="distilbert-base-uncased-finetuned-sst-2-english")
generator = pipeline("text-generation", model="gpt2")
print("Models loaded successfully!")
@app.get("/")
async def root():
"""根路径"""
return {
"message": "AI Model API Service",
"version": "1.0.0",
"endpoints": {
"health": "/health",
"classify": "/api/v1/classify",
"generate": "/api/v1/generate",
"metrics": "/metrics"
}
}
@app.get("/health")
async def health_check():
"""健康检查"""
return {"status": "healthy"}
@app.post("/api/v1/classify")
async def classify_text(text: str):
"""文本分类"""
start_time = time.time()
request_counter.labels(endpoint="/api/v1/classify", method="POST").inc()
try:
result = classifier(text)
duration = time.time() - start_time
request_duration.labels(endpoint="/api/v1/classify").observe(duration)
return {
"text": text,
"classification": result[0],
"processing_time": duration
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/api/v1/generate")
async def generate_text(prompt: str, max_length: int = 100):
"""文本生成"""
start_time = time.time()
request_counter.labels(endpoint="/api/v1/generate", method="POST").inc()
try:
result = generator(prompt, max_length=max_length, num_return_sequences=1)
duration = time.time() - start_time
request_duration.labels(endpoint="/api/v1/generate").observe(duration)
return {
"prompt": prompt,
"generated_text": result[0]["generated_text"],
"processing_time": duration
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/metrics")
async def metrics():
"""Prometheus指标"""
return Response(generate_latest(), media_type="text/plain")
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
第二步:配置Docker网络¶
2.1 创建Docker Compose配置¶
创建 docker-compose.yml:
version: '3.8'
services:
# AI模型API服务
api:
build: .
container_name: ai-api-service
ports:
- "8000:8000"
volumes:
- ./app:/app
- ./models:/models
environment:
- MODEL_PATH=/models
- OSS_ACCESS_KEY_ID=${OSS_ACCESS_KEY_ID}
- OSS_ACCESS_KEY_SECRET=${OSS_ACCESS_KEY_SECRET}
- OSS_BUCKET_NAME=${OSS_BUCKET_NAME}
- OSS_ENDPOINT=${OSS_ENDPOINT}
restart: unless-stopped
networks:
- ai-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
# Nginx反向代理
nginx:
image: nginx:alpine
container_name: ai-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- api
restart: unless-stopped
networks:
- ai-network
# Prometheus监控
prometheus:
image: prom/prometheus:latest
container_name: ai-prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
restart: unless-stopped
networks:
- ai-network
# Grafana可视化
grafana:
image: grafana/grafana:latest
container_name: ai-grafana
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
restart: unless-stopped
networks:
- ai-network
networks:
ai-network:
driver: bridge
volumes:
prometheus-data:
grafana-data:
2.2 创建环境变量文件¶
创建 .env:
OSS_ACCESS_KEY_ID=your-access-key-id
OSS_ACCESS_KEY_SECRET=your-access-key-secret
OSS_BUCKET_NAME=your-bucket-name
OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com
2.3 启动服务¶
第三步:使用Nginx反向代理¶
3.1 创建Nginx配置文件¶
创建 nginx/nginx.conf:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# 限制请求体大小(用于文件上传)
client_max_body_size 10M;
# 上游服务器
upstream api_backend {
server api:8000;
keepalive 32;
}
# HTTP重定向到HTTPS
server {
listen 80;
server_name api.yourdomain.com;
return 301 https://$server_name$request_uri;
}
# HTTPS配置
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
# SSL证书配置
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# SSL优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# API限流
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req zone=api_limit burst=20 nodelay;
# API端点
location /api/v1/ {
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# 健康检查
location /health {
proxy_pass http://api_backend/health;
access_log off;
}
# Prometheus指标
location /metrics {
proxy_pass http://api_backend/metrics;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
# 根路径
location / {
proxy_pass http://api_backend/;
}
}
}
3.2 配置SSL证书¶
# 停止Nginx容器
docker-compose stop nginx
# 获取SSL证书
sudo certbot certonly --standalone -d api.yourdomain.com
# 复制证书到项目目录
sudo cp /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem ~/ai-api-service/nginx/ssl/
sudo cp /etc/letsencrypt/live/api.yourdomain.com/privkey.pem ~/ai-api-service/nginx/ssl/
# 设置权限
sudo chmod 644 ~/ai-api-service/nginx/ssl/*.pem
# 重启Nginx
docker-compose start nginx
第四步:配置域名和SSL证书¶
4.1 配置DNS解析¶
在域名注册商的DNS管理页面,添加以下记录:
4.2 配置SSL证书自动续期¶
# 创建续期脚本
cat > ~/ai-api-service/renew-ssl.sh << 'EOF'
#!/bin/bash
# 停止Nginx
docker-compose stop nginx
# 续期证书
sudo certbot renew
# 复制证书
sudo cp /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem ~/ai-api-service/nginx/ssl/
sudo cp /etc/letsencrypt/live/api.yourdomain.com/privkey.pem ~/ai-api-service/nginx/ssl/
# 重启Nginx
docker-compose start nginx
EOF
# 添加执行权限
chmod +x ~/ai-api-service/renew-ssl.sh
# 添加定时任务
crontab -e
# 添加以下行(每月1号凌晨3点执行)
0 3 1 * * /home/user/ai-api-service/renew-ssl.sh
第五步:使用OSS存储模型文件¶
5.1 创建OSS存储桶¶
登录阿里云控制台: 1. 选择"对象存储OSS" 2. 点击"创建Bucket" 3. 配置Bucket: - Bucket名称:ai-models-bucket - 地域:选择离服务器近的地域 - 存储类型:标准存储 - 读写权限:私有 4. 点击"确定"
5.2 配置OSS访问权限¶
# 创建OSS配置文件
cat > app/oss_config.py << 'EOF'
import oss2
# OSS配置
OSS_ACCESS_KEY_ID = "your-access-key-id"
OSS_ACCESS_KEY_SECRET = "your-access-key-secret"
OSS_BUCKET_NAME = "ai-models-bucket"
OSS_ENDPOINT = "oss-cn-hangzhou.aliyuncs.com"
# 创建OSS客户端
auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)
def upload_model(file_path, object_name):
"""上传模型文件到OSS"""
bucket.put_object_from_file(object_name, file_path)
print(f"模型文件上传成功: {object_name}")
def download_model(object_name, file_path):
"""从OSS下载模型文件"""
bucket.get_object_to_file(object_name, file_path)
print(f"模型文件下载成功: {object_name}")
def get_model_url(object_name, expires=3600):
"""获取模型文件的临时访问URL"""
url = bucket.sign_url('GET', object_name, expires)
return url
EOF
5.3 上传模型文件¶
# 创建上传脚本
cat > upload_models.py << 'EOF'
from app.oss_config import upload_model
import os
# 模型文件列表
model_files = [
("models/text-classifier.pt", "models/text-classifier.pt"),
("models/text-generator.pt", "models/text-generator.pt"),
]
# 上传模型文件
for local_path, object_name in model_files:
if os.path.exists(local_path):
upload_model(local_path, object_name)
else:
print(f"文件不存在: {local_path}")
EOF
# 执行上传
python upload_models.py
第六步:配置CDN加速API访问¶
6.1 开通CDN服务¶
登录阿里云CDN控制台: 1. 选择"CDN"服务 2. 点击"添加域名" 3. 配置CDN: - 加速域名:api.yourdomain.com - 业务类型:API加速 - 源站类型:IP源站 - 源站地址:your-server-ip - 端口:443 4. 点击"确定"
6.2 配置CDN缓存规则¶
6.3 配置CDN HTTPS¶
在CDN控制台配置HTTPS: 1. 选择"HTTPS配置" 2. 开启HTTPS 3. 选择证书类型:免费证书 4. 开启HTTP/2 5. 开启强制HTTPS
6.4 配置CDN限流¶
在CDN控制台配置限流: 1. 选择"访问控制" → "限流" 2. 配置限流规则: - 单IP请求频率:100次/秒 - 单IP带宽限制:10Mbps
📊 项目总结¶
完成的功能: ✅ 使用Docker打包AI模型服务 ✅ 配置Docker网络和容器编排 ✅ 使用Nginx反向代理API请求 ✅ 配置域名和SSL证书 ✅ 使用OSS存储模型文件 ✅ 配置CDN加速API访问
技术要点: - FastAPI提供高性能API服务 - Docker实现应用容器化部署 - Nginx作为反向代理处理HTTP请求 - OSS提供对象存储服务 - CDN加速API访问,提升响应速度 - Prometheus + Grafana监控服务状态
🤖 实战案例三(补充):大模型API服务部署¶
📋 场景描述¶
部署一个生产级的大模型API服务(如GPT、Claude等),支持流式输出、高并发访问,具备完善的认证、限流和监控机制。
🛠️ 技术栈¶
- AI框架:vLLM / TGI(Text Generation Inference)
- API框架:FastAPI + SSE(流式传输)
- 网关:Nginx / Traefik
- 缓存:Redis
- 监控:Prometheus + Grafana
- 日志:ELK Stack
- 容器化:Docker + Kubernetes
第一步:模型服务架构设计¶
┌─────────────────────────────────────────────────────────────┐
│ 客户端层 │
│ Web App / Mobile App / Third-party API │
└──────────────────────┬──────────────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────────────────────┐
│ 网关层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Nginx │ │ 限流器 │ │ 负载均衡 │ │
│ │ (SSL/TLS) │ │ (Redis) │ │ │ │
│ └──────┬──────┘ └─────────────┘ └─────────────┘ │
└─────────┼───────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 服务层 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ FastAPI 服务 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 认证中间件 │ │ 限流中间件 │ │ 日志中间件 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ vLLM / TGI 推理引擎 │ │ │
│ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │
│ │ │ │ Model 1 │ │ Model 2 │ │ Model 3 │ │ │ │
│ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 基础设施层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Redis │ │ Prometheus │ │ Grafana │ │
│ │ (缓存/队列) │ │ (指标收集) │ │ (可视化) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
第二步:使用vLLM部署大模型¶
2.1 安装vLLM¶
# 创建虚拟环境
python -m venv vllm-env
source vllm-env/bin/activate
# 安装vLLM
pip install vllm
# 安装依赖
pip install fastapi uvicorn sse-starlette
2.2 创建模型服务¶
# llm_service.py
from vllm import LLM, SamplingParams
from fastapi import FastAPI, HTTPException, Depends
from fastapi.responses import StreamingResponse
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import BaseModel # Pydantic数据验证模型
from typing import List, Optional, AsyncGenerator
import asyncio
import json
import redis
import time
from functools import wraps
# 初始化模型
print("Loading LLM model...")
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf", # 或其他模型
tensor_parallel_size=1, # GPU数量
gpu_memory_utilization=0.9,
max_num_seqs=256,
)
print("Model loaded successfully!")
# FastAPI应用
app = FastAPI(title="LLM API Service")
security = HTTPBearer()
# Redis连接
redis_client = redis.Redis(host='localhost', port=6379, db=0)
# 数据模型
class ChatMessage(BaseModel):
role: str
content: str
class ChatCompletionRequest(BaseModel):
model: str = "llama-2-7b"
messages: List[ChatMessage]
temperature: float = 0.7
max_tokens: int = 512
stream: bool = False
top_p: float = 1.0
frequency_penalty: float = 0.0
presence_penalty: float = 0.0
class ChatCompletionResponse(BaseModel):
id: str
object: str
created: int
model: str
choices: List[dict]
usage: dict
# 认证中间件
async def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
"""验证API Token"""
token = credentials.credentials
# 这里应该查询数据库或缓存验证token
# 简化示例:检查token是否在Redis中
user_id = redis_client.get(f"token:{token}")
if not user_id:
raise HTTPException(status_code=401, detail="Invalid token")
return user_id.decode()
# 限流装饰器
def rate_limit(requests_per_minute: int = 60):
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs): # *args接收任意位置参数;**kwargs接收任意关键字参数
# 获取用户ID(从依赖注入)
user_id = kwargs.get('user_id')
if not user_id:
return await func(*args, **kwargs)
# 检查限流
key = f"rate_limit:{user_id}"
current = redis_client.get(key)
if current and int(current) >= requests_per_minute:
raise HTTPException(status_code=429, detail="Rate limit exceeded")
# 增加计数
pipe = redis_client.pipeline()
pipe.incr(key)
pipe.expire(key, 60)
pipe.execute()
return await func(*args, **kwargs)
return wrapper
return decorator
# 格式化对话历史
def format_messages(messages: List[ChatMessage]) -> str:
"""将消息列表格式化为模型输入"""
formatted = ""
for msg in messages:
if msg.role == "system":
formatted += f"[INST] <<SYS>>\n{msg.content}\n<</SYS>>\n\n"
elif msg.role == "user":
formatted += f"{msg.content} [/INST] "
elif msg.role == "assistant":
formatted += f"{msg.content} </s><s>[INST] "
return formatted
# 非流式生成
@app.post("/v1/chat/completions", response_model=ChatCompletionResponse)
@rate_limit(requests_per_minute=60)
async def chat_completion(
request: ChatCompletionRequest,
user_id: str = Depends(verify_token)
):
"""聊天补全接口(非流式)"""
start_time = time.time()
# 格式化输入
prompt = format_messages(request.messages)
# 设置采样参数
sampling_params = SamplingParams(
temperature=request.temperature,
max_tokens=request.max_tokens,
top_p=request.top_p,
frequency_penalty=request.frequency_penalty,
presence_penalty=request.presence_penalty,
)
# 生成回复
outputs = llm.generate([prompt], sampling_params)
generated_text = outputs[0].outputs[0].text
# 计算token数(简化)
prompt_tokens = len(prompt.split())
completion_tokens = len(generated_text.split())
return ChatCompletionResponse(
id=f"chatcmpl-{int(time.time())}",
object="chat.completion",
created=int(time.time()),
model=request.model,
choices=[{
"index": 0,
"message": {
"role": "assistant",
"content": generated_text
},
"finish_reason": "stop"
}],
usage={
"prompt_tokens": prompt_tokens,
"completion_tokens": completion_tokens,
"total_tokens": prompt_tokens + completion_tokens
}
)
# 流式生成
async def generate_stream(prompt: str, sampling_params: SamplingParams) -> AsyncGenerator[str, None]:
"""流式生成器"""
# vLLM的流式生成
stream = llm.generate([prompt], sampling_params, stream=True)
for output in stream:
text = output.outputs[0].text
chunk = {
"id": f"chatcmpl-{int(time.time())}",
"object": "chat.completion.chunk",
"created": int(time.time()),
"model": "llama-2-7b",
"choices": [{
"index": 0,
"delta": {"content": text},
"finish_reason": None
}]
}
yield f"data: {json.dumps(chunk)}\n\n" # yield生成器:惰性产出值,节省内存
await asyncio.sleep(0.01) # 控制流速
# 发送结束标记
yield "data: [DONE]\n\n"
@app.post("/v1/chat/completions")
@rate_limit(requests_per_minute=60)
async def chat_completion_stream(
request: ChatCompletionRequest,
user_id: str = Depends(verify_token)
):
"""聊天补全接口(流式)"""
if not request.stream:
return await chat_completion(request, user_id)
prompt = format_messages(request.messages)
sampling_params = SamplingParams(
temperature=request.temperature,
max_tokens=request.max_tokens,
top_p=request.top_p,
)
return StreamingResponse(
generate_stream(prompt, sampling_params),
media_type="text/event-stream"
)
# 健康检查
@app.get("/health")
async def health_check():
"""健康检查"""
return {
"status": "healthy",
"model": "llama-2-7b",
"gpu_available": True,
"queue_length": 0
}
# 模型信息
@app.get("/v1/models")
async def list_models():
"""列出可用模型"""
return {
"object": "list",
"data": [
{
"id": "llama-2-7b",
"object": "model",
"created": 1677610602,
"owned_by": "meta"
}
]
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
2.3 创建Dockerfile¶
# Dockerfile
FROM nvidia/cuda:11.8.0-runtime-ubuntu22.04 # FROM指定基础镜像
# 设置工作目录
WORKDIR /app # WORKDIR设置工作目录
# 安装Python和依赖
RUN apt-get update && apt-get install -y \ # RUN在构建时执行命令
python3-pip \
python3-dev \
git \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt . # COPY将文件复制到镜像中
# 安装Python依赖
RUN pip3 install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY llm_service.py .
# 暴露端口
EXPOSE 8000 # EXPOSE声明容器监听的端口
# 启动命令
CMD ["python3", "-m", "uvicorn", "llm_service:app", "--host", "0.0.0.0", "--port", "8000"] # CMD容器启动时执行的默认命令
# requirements.txt
vllm==0.2.1
fastapi==0.104.1
uvicorn[standard]==0.24.0
sse-starlette==1.6.5
redis==5.0.1
pydantic==2.5.0
python-jose[cryptography]==3.3.0
passlib[bcrypt]==1.7.4
prometheus-client==0.19.0
第三步:配置Nginx网关¶
# nginx.conf
upstream llm_backend {
least_conn; # 最少连接负载均衡
server llm-api-1:8000 max_fails=3 fail_timeout=30s;
server llm-api-2:8000 max_fails=3 fail_timeout=30s;
server llm-api-3:8000 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# 限流配置
limit_req_zone $binary_remote_addr zone=llm_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=llm_conn:10m;
server {
listen 80;
server_name api.llm-service.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.llm-service.com;
# SSL证书
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# 客户端请求体大小限制
client_max_body_size 10M;
# API限流
limit_req zone=llm_limit burst=20 nodelay;
limit_conn llm_conn 10;
# 流式API端点
location /v1/chat/completions {
proxy_pass http://llm_backend;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 流式传输设置
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
# CORS
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
}
# 健康检查
location /health {
proxy_pass http://llm_backend/health;
access_log off;
}
# 指标端点(限制访问)
location /metrics {
proxy_pass http://llm_backend/metrics;
allow 10.0.0.0/8;
deny all;
}
}
第四步:部署到Kubernetes¶
# k8s-deployment.yaml
apiVersion: apps/v1 # apiVersion指定K8s API版本
kind: Deployment # kind指定资源类型
metadata:
name: llm-api
labels:
app: llm-api
spec: # spec定义资源的期望状态
replicas: 3
selector:
matchLabels:
app: llm-api
template:
metadata:
labels:
app: llm-api
spec:
containers:
- name: llm-api
image: your-registry/llm-api:latest
ports:
- containerPort: 8000
resources:
limits:
nvidia.com/gpu: 1 # 请求1个GPU
memory: "16Gi"
cpu: "8"
requests:
memory: "8Gi"
cpu: "4"
env:
- name: REDIS_HOST
value: "redis-service"
- name: MODEL_PATH
value: "/models"
volumeMounts:
- name: model-storage
mountPath: /models
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 5
volumes:
- name: model-storage
persistentVolumeClaim:
claimName: model-pvc
nodeSelector:
accelerator: nvidia-tesla-a100 # 选择GPU节点
--- # YAML文档分隔符
apiVersion: v1
kind: Service
metadata:
name: llm-api-service
spec:
selector:
app: llm-api
ports:
- port: 8000
targetPort: 8000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: llm-api-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- api.llm-service.com
secretName: llm-api-tls
rules:
- host: api.llm-service.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: llm-api-service
port:
number: 8000
第五步:监控和日志¶
# monitoring.py
from prometheus_client import Counter, Histogram, Gauge, generate_latest # Counter计数器:统计元素出现次数
from fastapi import Request
import time
# 定义指标
request_count = Counter('llm_requests_total', 'Total requests', ['endpoint', 'method', 'status'])
request_duration = Histogram('llm_request_duration_seconds', 'Request duration', ['endpoint'])
tokens_generated = Counter('llm_tokens_generated_total', 'Total tokens generated', ['model'])
active_requests = Gauge('llm_active_requests', 'Number of active requests')
queue_length = Gauge('llm_queue_length', 'Current queue length')
def monitor_request(endpoint: str):
"""请求监控装饰器"""
def decorator(func):
async def wrapper(*args, **kwargs): # async def定义异步函数;用await调用
start_time = time.time()
active_requests.inc()
try: # try/except捕获异常
result = await func(*args, **kwargs) # await等待异步操作完成
status = 200
return result
except Exception as e:
status = 500
raise
finally:
duration = time.time() - start_time
request_duration.labels(endpoint=endpoint).observe(duration)
request_count.labels(endpoint=endpoint, method='POST', status=status).inc()
active_requests.dec()
return wrapper
return decorator
📊 项目总结¶
完成的功能: ✅ 使用vLLM部署大模型推理服务 ✅ 实现流式输出(SSE) ✅ 配置API认证和限流 ✅ 使用Nginx作为网关和负载均衡 ✅ 部署到Kubernetes集群 ✅ 配置监控和日志
技术要点: - vLLM提供高性能的模型推理 - FastAPI支持异步流式传输 - Redis实现分布式限流 - Nginx处理负载均衡和SSL - Kubernetes实现弹性扩缩容 - Prometheus + Grafana监控系统
性能优化: - 使用连续批处理提升吞吐量 - 配置GPU内存优化 - 启用KV Cache复用 - 使用流式传输降低延迟
📁 实战案例四:搭建文件共享服务¶
📋 场景描述¶
搭建一个文件共享服务,使用OSS作为存储后端,支持大文件上传下载,配置自定义域名,使用CDN加速,配置防盗链保护资源。
🛠️ 技术栈¶
- 存储后端:阿里云OSS
- Web服务:Nginx
- CDN:阿里云CDN
- 域名:自定义域名
- 防盗链:Referer检查
第一步:使用OSS作为存储后端¶
1.1 创建OSS存储桶¶
登录阿里云控制台: 1. 选择"对象存储OSS" 2. 点击"创建Bucket" 3. 配置Bucket: - Bucket名称:file-share-bucket - 地域:选择离用户近的地域 - 存储类型:标准存储 - 读写权限:私有 4. 点击"确定"
1.2 配置OSS访问权限¶
# 创建OSS配置文件
cat > oss_config.py << 'EOF'
import oss2
import os
# 从环境变量获取OSS配置
OSS_ACCESS_KEY_ID = os.getenv('OSS_ACCESS_KEY_ID')
OSS_ACCESS_KEY_SECRET = os.getenv('OSS_ACCESS_KEY_SECRET')
OSS_BUCKET_NAME = os.getenv('OSS_BUCKET_NAME')
OSS_ENDPOINT = os.getenv('OSS_ENDPOINT')
# 创建OSS客户端
auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)
class OSSFileManager:
"""OSS文件管理器"""
def __init__(self):
self.bucket = bucket
def upload_file(self, file_path, object_name):
"""上传文件"""
result = self.bucket.put_object_from_file(object_name, file_path)
return {
'status': 'success',
'object_name': object_name,
'etag': result.etag
}
def download_file(self, object_name, file_path):
"""下载文件"""
self.bucket.get_object_to_file(object_name, file_path)
return {
'status': 'success',
'file_path': file_path
}
def delete_file(self, object_name):
"""删除文件"""
self.bucket.delete_object(object_name)
return {
'status': 'success',
'object_name': object_name
}
def list_files(self, prefix=''):
"""列出文件"""
files = []
for obj in oss2.ObjectIterator(self.bucket, prefix=prefix):
files.append({
'name': obj.key,
'size': obj.size,
'last_modified': obj.last_modified,
'etag': obj.etag
})
return files
def get_file_url(self, object_name, expires=3600):
"""获取文件临时访问URL"""
url = self.bucket.sign_url('GET', object_name, expires)
return url
def create_upload_url(self, object_name, expires=3600):
"""创建上传URL"""
url = self.bucket.sign_url('PUT', object_name, expires)
return url
EOF
第二步:配置OSS访问权限¶
2.1 创建RAM用户¶
登录阿里云RAM控制台: 1. 选择"用户" → "创建用户" 2. 配置用户: - 用户名:file-share-user - 访问方式:编程访问 3. 创建AccessKey 4. 记录AccessKey ID和AccessKey Secret
2.2 配置权限策略¶
创建自定义权限策略:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"oss:PutObject",
"oss:GetObject",
"oss:DeleteObject",
"oss:ListObjects"
],
"Resource": [
"acs:oss:*:*:file-share-bucket/*"
]
}
]
}
将策略授权给RAM用户。
2.3 配置跨域访问(CORS)¶
在OSS控制台配置CORS: 1. 选择"数据管理" → "跨域设置" 2. 点击"创建规则" 3. 配置规则: - 来源:*(或指定域名) - 允许Methods:GET、POST、PUT、DELETE、HEAD - 允许Headers:* - 暴露Headers:ETag、x-oss-request-id - 缓存时间:600
第三步:配置自定义域名¶
3.1 绑定自定义域名¶
在OSS控制台: 1. 选择"域名管理" → "绑定用户域名" 2. 配置域名: - 用户域名:files.yourdomain.com - 权限:私有 - HTTPS:开启 3. 点击"确定"
3.2 配置DNS解析¶
在域名注册商的DNS管理页面,添加CNAME记录:
3.3 验证域名解析¶
第四步:设置CDN加速¶
4.1 开通CDN服务¶
登录阿里云CDN控制台: 1. 选择"CDN"服务 2. 点击"添加域名" 3. 配置CDN: - 加速域名:files.yourdomain.com - 业务类型:图片小文件 - 源站类型:OSS域名 - 源站地址:file-share-bucket.oss-cn-hangzhou.aliyuncs.com 4. 点击"确定"
4.2 配置CDN缓存规则¶
文件类型:.jpg;.jpeg;.png;.gif;.pdf;.zip;.rar;.7z;.tar;.gz
缓存时间:30天
文件类型:.html;.json;.xml;.txt
缓存时间:1小时
文件类型:*
缓存时间:不缓存
4.3 配置CDN HTTPS¶
在CDN控制台配置HTTPS: 1. 选择"HTTPS配置" 2. 开启HTTPS 3. 选择证书类型:免费证书 4. 开启HTTP/2 5. 开启强制HTTPS
第五步:配置防盗链¶
5.1 配置Referer防盗链¶
在CDN控制台配置Referer防盗链: 1. 选择"访问控制" → "Referer防盗链" 2. 开启防盗链 3. 配置Referer白名单: - https://yourdomain.com - https://www.yourdomain.com 4. 配置Referer黑名单(可选) 5. 选择"允许空Referer":否
5.2 配置URL鉴权¶
在CDN控制台配置URL鉴权: 1. 选择"访问控制" → "URL鉴权" 2. 开启鉴权 3. 配置鉴权密钥: - 主Key:your-primary-key - 备Key:your-backup-key 4. 配置鉴权参数: - 鉴权类型:Type A - 有效时间:1800秒
5.3 生成鉴权URL¶
# 创建URL鉴权工具
cat > url_auth.py << 'EOF'
import hashlib
import time
from urllib.parse import quote
def generate_auth_url(url, key, expire=1800):
"""生成鉴权URL"""
# 获取当前时间戳
timestamp = int(time.time()) + expire
# 生成鉴权字符串
auth_string = f"{timestamp}-{key}"
# 计算MD5
md5 = hashlib.md5()
md5.update(auth_string.encode('utf-8'))
auth_sign = md5.hexdigest()
# 构建鉴权URL
auth_url = f"{url}?auth_key={timestamp}-{auth_sign}"
return auth_url
# 使用示例
url = "https://files.yourdomain.com/example.pdf"
key = "your-primary-key"
auth_url = generate_auth_url(url, key)
print(auth_url)
EOF
📊 项目总结¶
完成的功能: ✅ 使用OSS作为存储后端 ✅ 配置OSS访问权限和CORS ✅ 配置自定义域名 ✅ 设置CDN加速 ✅ 配置防盗链保护资源
技术要点: - OSS提供对象存储服务 - RAM用户实现细粒度权限控制 - 自定义域名提升品牌形象 - CDN加速文件访问速度 - Referer防盗链保护资源安全 - URL鉴权实现访问控制
📊 实战案例五:监控网络流量¶
📋 场景描述¶
搭建网络流量监控系统,实时监控服务器网络状态,分析网络流量,使用Prometheus收集指标,Grafana可视化展示。
🛠️ 技术栈¶
- 抓包工具:tcpdump
- 监控工具:Prometheus
- 可视化:Grafana
- 日志收集:Clash日志
- 告警:Alertmanager
第一步:使用tcpdump抓包分析¶
1.1 安装tcpdump¶
1.2 基本抓包命令¶
# 抓取所有网络包
sudo tcpdump -i any
# 抓取指定网卡
sudo tcpdump -i eth0
# 抓取指定数量的包
sudo tcpdump -c 100
# 保存到文件
sudo tcpdump -w capture.pcap
# 读取抓包文件
sudo tcpdump -r capture.pcap
1.3 高级抓包命令¶
# 抓取HTTP请求
sudo tcpdump -i any -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
# 抓取HTTPS请求(只能看到握手信息)
sudo tcpdump -i any 'tcp port 443'
# 抓取指定IP的包
sudo tcpdump host 192.168.1.100
# 抓取指定端口的包
sudo tcpdump port 8080
# 抓取指定协议的包
sudo tcpdump icmp
# 抓取指定网段的包
sudo tcpdump net 192.168.1.0/24
# 抓取TCP SYN包(连接建立)
sudo tcpdump 'tcp[tcpflags] & tcp-syn != 0'
# 抓取TCP FIN包(连接关闭)
sudo tcpdump 'tcp[tcpflags] & tcp-fin != 0'
1.4 分析网络流量¶
# 统计流量
sudo tcpdump -i any -nn | awk '{print $3}' | sort | uniq -c | sort -rn
# 分析HTTP请求
sudo tcpdump -i any -A -s 0 'tcp port 80' | grep -E "GET|POST|PUT|DELETE"
# 分析DNS查询
sudo tcpdump -i any -nn 'udp port 53'
# 分析SSH连接
sudo tcpdump -i any -nn 'tcp port 22'
第二步:配置Clash日志¶
2.1 配置Clash日志级别¶
在Clash配置文件中添加日志配置:
# Clash配置文件
log-level: info
secret: "your-secret-key"
# 日志文件路径
external-controller: 127.0.0.1:9090
2.2 查看Clash日志¶
# 查看Clash日志
# Windows: %USERPROFILE%\.config\clash\logs
# Mac: ~/.config/clash/logs/
# 实时查看日志
tail -f ~/.config/clash/logs/clash.log
# 查看错误日志
grep ERROR ~/.config/clash/logs/clash.log
2.3 分析Clash日志¶
# 统计连接数
grep "TCP" ~/.config/clash/logs/clash.log | wc -l
# 统计代理使用情况
grep "proxy" ~/.config/clash/logs/clash.log | awk '{print $NF}' | sort | uniq -c | sort -rn # awk文本处理:按列提取和格式化数据
# 查看失败的连接
grep "FAILED" ~/.config/clash/logs/clash.log
第三步:监控服务器网络状态¶
3.1 安装监控工具¶
# 安装ifstat(网络流量监控)
sudo apt install ifstat -y
# 安装nethogs(进程网络使用)
sudo apt install nethogs -y
# 安装iftop(实时网络流量)
sudo apt install iftop -y
3.2 使用ifstat监控网络¶
3.3 使用nethogs监控进程¶
3.4 使用iftop监控流量¶
第四步:使用Prometheus+Grafana监控¶
4.1 安装Prometheus¶
# 创建Prometheus目录
mkdir -p ~/monitoring/prometheus
cd ~/monitoring/prometheus
# 下载Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz
# 解压
tar xvfz prometheus-2.48.0.linux-amd64.tar.gz
cd prometheus-2.48.0.linux-amd64
# 创建配置文件
cat > prometheus.yml << 'EOF'
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['localhost:9100']
- job_name: 'clash'
static_configs:
- targets: ['localhost:9090']
metrics_path: '/metrics'
4.2 安装Node Exporter¶
# 下载Node Exporter
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
# 解压
tar xvfz node_exporter-1.7.0.linux-amd64.tar.gz
cd node_exporter-1.7.0.linux-amd64
# 启动Node Exporter
./node_exporter &
# 验证
curl http://localhost:9100/metrics
4.3 使用Docker Compose部署¶
创建 docker-compose.yml:
version: '3.8'
services:
# Prometheus
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
restart: unless-stopped
networks:
- monitoring
# Grafana
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
restart: unless-stopped
networks:
- monitoring
# Node Exporter
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
restart: unless-stopped
networks:
- monitoring
networks:
monitoring:
driver: bridge
volumes:
prometheus-data:
grafana-data:
4.4 启动监控服务¶
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 访问Prometheus
# http://your-server-ip:9090
# 访问Grafana
# http://your-server-ip:3000
# 默认用户名密码:admin/admin
4.5 配置Grafana仪表板¶
- 登录Grafana(http://your-server-ip:3000)
- 添加数据源:
- 点击"Configuration" → "Data Sources"
- 点击"Add data source"
- 选择"Prometheus"
- 配置URL:
http://prometheus:9090 - 点击"Save & Test"
- 导入仪表板:
- 点击"+" → "Import"
- 输入仪表板ID:
1860(Node Exporter Full) - 点击"Load"
- 选择Prometheus数据源
- 点击"Import"
📊 项目总结¶
完成的功能: ✅ 使用tcpdump抓包分析网络流量 ✅ 配置Clash日志监控 ✅ 监控服务器网络状态 ✅ 使用Prometheus收集指标 ✅ 使用Grafana可视化展示
技术要点: - tcpdump提供强大的网络抓包能力 - Clash日志记录代理使用情况 - ifstat/nethogs/iftop监控网络流量 - Prometheus收集和存储监控指标 - Grafana可视化展示监控数据
🔧 故障排查指南¶
网络连接问题排查流程¶
1. 检查网络连接¶
# 检查本地网络
ping 8.8.8.8
# 检查DNS解析
nslookup www.google.com
# 检查端口连通性
telnet www.google.com 80
# 使用curl测试
curl -I https://www.google.com
2. 检查防火墙¶
3. 检查路由¶
DNS问题排查¶
1. 检查DNS配置¶
# 查看DNS配置
cat /etc/resolv.conf
# 测试DNS解析
nslookup www.google.com
dig www.google.com
# 测试不同DNS服务器
nslookup www.google.com 8.8.8.8
nslookup www.google.com 114.114.114.114
2. 清除DNS缓存¶
# Linux清除DNS缓存
sudo systemd-resolve --flush-caches
# Mac清除DNS缓存
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
# Windows清除DNS缓存
ipconfig /flushdns
3. 检查DNS记录¶
# 查询A记录
dig A myblog.com
# 查询MX记录
dig MX myblog.com
# 查询TXT记录
dig TXT myblog.com
# 查询所有记录
dig ANY myblog.com
代理问题排查¶
1. 检查代理配置¶
# 检查环境变量
echo $HTTP_PROXY
echo $HTTPS_PROXY
echo $NO_PROXY
# 检查Clash配置
cat ~/.config/clash/config.yaml
# 检查Clash日志
tail -f ~/.config/clash/logs/clash.log
2. 测试代理连接¶
# 测试代理是否工作
curl -x http://127.0.0.1:7890 https://www.google.com
# 测试SOCKS代理
curl --socks5 127.0.0.1:7891 https://www.google.com
# 查看代理日志
grep "proxy" ~/.config/clash/logs/clash.log
3. 检查代理服务器¶
# 连接到VPS
ssh root@your-vps-ip
# 检查V2Ray状态
systemctl status v2ray
# 查看V2Ray日志
journalctl -u v2ray -f
# 检查端口监听
netstat -tlnp | grep 10086 # grep文本搜索:按模式匹配行
Docker网络问题排查¶
1. 检查Docker网络¶
# 查看Docker网络
docker network ls
# 查看网络详情
docker network inspect bridge
# 查看容器网络
docker inspect <container-name> | grep -A 10 Networks # |管道:将前一命令的输出作为后一命令的输入
2. 检查容器连接¶
# 进入容器
docker exec -it <container-name> /bin/bash
# 测试网络连接
ping google.com
curl -I https://www.google.com
# 查看DNS配置
cat /etc/resolv.conf
3. 检查端口映射¶
# 查看端口映射
docker port <container-name>
# 查看容器日志
docker logs <container-name>
# 重启容器
docker restart <container-name>
💡 最佳实践¶
网络安全建议¶
1. 使用HTTPS¶
# 强制HTTPS
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
# 配置强加密套件
server {
listen 443 ssl http2;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
2. 配置安全头¶
# 安全头配置
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
3. 配置防火墙¶
# 启用防火墙
sudo ufw enable
# 允许SSH
sudo ufw allow 22
# 允许HTTP/HTTPS
sudo ufw allow 80
sudo ufw allow 443
# 查看防火墙状态
sudo ufw status
4. 使用SSH密钥认证¶
# 生成SSH密钥对
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 将公钥复制到服务器
ssh-copy-id root@your-server-ip
# 禁用密码登录
sudo nano /etc/ssh/sshd_config
# 修改:PasswordAuthentication no
# 重启SSH服务
sudo systemctl restart sshd
性能优化建议¶
1. 启用Gzip压缩¶
# Nginx Gzip配置
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;
2. 配置缓存¶
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# HTML文件缓存
location ~* \.html$ {
expires 1h;
add_header Cache-Control "public";
}
3. 使用CDN加速¶
# 配置CDN缓存规则
# 静态资源:30天
# HTML文件:1小时
# API响应:不缓存
# 使用CDN域名
https://cdn.yourdomain.com/static/logo.png
4. 优化数据库查询¶
# 使用索引
CREATE INDEX idx_user_email ON users(email);
# 使用缓存
from functools import lru_cache
@lru_cache(maxsize=128)
def get_user(user_id):
return User.query.get(user_id)
成本优化建议¶
1. 选择合适的服务器配置¶
小型博客:
- CPU: 1核
- 内存: 1GB
- 带宽: 1Mbps
- 价格: $5/月
中型应用:
- CPU: 2核
- 内存: 4GB
- 带宽: 3Mbps
- 价格: $20/月
大型应用:
- CPU: 4核
- 内存: 8GB
- 带宽: 5Mbps
- 价格: $40/月
2. 使用对象存储¶
3. 使用CDN节省带宽¶
4. 定期清理无用资源¶
# 清理Docker镜像
docker image prune -a
# 清理Docker容器
docker container prune
# 清理Docker卷
docker volume prune
# 清理日志文件
find /var/log -type f -name "*.log" -mtime +30 -delete
备份和容灾建议¶
1. 数据备份策略¶
# 数据库备份
# 每天自动备份
0 2 * * * mysqldump -u root -p database > backup_$(date +\%Y\%m\%d).sql # $()命令替换:执行命令并获取输出
# 保留30天的备份
find /backup -name "backup_*.sql" -mtime +30 -delete
# 异地备份
# 将备份文件上传到OSS
ossutil cp /backup/backup_$(date +\%Y\%m\%d).sql oss://backup-bucket/
2. 配置自动备份¶
# Docker Compose配置备份
version: '3.8'
services: # services定义各个服务容器
backup:
image: alpine:latest
volumes:
- ./data:/data
- ./backup:/backup
command: >
sh -c "tar czf /backup/data_$(date +%Y%m%d).tar.gz /data &&
find /backup -name 'data_*.tar.gz' -mtime +7 -delete"
restart: "no"
3. 配置监控告警¶
# Prometheus告警规则
groups:
- name: alert_rules
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage detected"
description: "CPU usage is above 80% for more than 5 minutes"
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High memory usage detected"
description: "Memory usage is above 80% for more than 5 minutes"
4. 配置灾难恢复¶
# 准备备用服务器
# 1. 购买备用VPS
# 2. 配置相同的环境
# 3. 定期同步数据
# 4. 配置DNS切换
# DNS切换脚本
cat > switch-dns.sh << 'EOF'
#!/bin/bash
# 切换DNS到备用服务器
# 更新DNS记录
# 通知相关人员
EOF
📝 总结¶
学习要点回顾¶
通过本章的实战案例,我们学习了:
- 域名和DNS:
- 购买和配置域名
- DNS解析和配置
-
CDN加速配置
-
服务器和SSH:
- 购买和配置服务器
- SSH连接和密钥认证
-
服务器安全配置
-
代理和VPN:
- 配置科学上网环境
- Clash客户端配置
-
TUN模式和PAC规则
-
Docker网络:
- Docker容器化部署
- Docker网络配置
-
Docker Compose编排
-
云服务和CDN:
- OSS对象存储
- CDN加速配置
-
负载均衡和反向代理
-
网络监控:
- tcpdump抓包分析
- Prometheus监控
-
Grafana可视化
-
故障排查:
- 网络连接问题排查
- DNS问题排查
- 代理问题排查
- Docker网络问题排查
实战技能提升¶
通过完成这些实战案例,你应该能够:
✅ 独立搭建完整的Web应用 ✅ 配置稳定的科学上网环境 ✅ 部署AI模型API服务 ✅ 搭建文件共享服务 ✅ 监控和分析网络流量 ✅ 排查常见网络问题
下一步学习建议¶
- 深入学习:
- 学习更多网络协议(HTTP/2、HTTP/3)
- 学习负载均衡和高可用架构
-
学习网络安全和渗透测试
-
实践项目:
- 搭建个人博客网站
- 部署自己的AI应用
-
搭建文件共享服务
-
持续优化:
- 优化网络性能
- 提升安全性
- 降低成本
🎉 恭喜你!¶
你已经完成了网络学习的全部内容!从基础理论到实战应用,你已经掌握了网络技术的核心知识和实际应用能力。
继续学习,不断实践,你将成为网络技术专家! 🚀
文档版本:v1.0 最后更新:2026年1月 作者:AI学习创作团队