跳转至

08 - 实战应用场景

本章核心: 通过真实项目案例,综合运用所学网络知识解决实际问题


📖 章节导航

前序章节: 06-云服务与CDN.md07-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

购买步骤

Text Only
1. 搜索想要注册的域名(如:myblog.com)
2. 检查域名是否可用
3. 选择注册年限(1-10年)
4. 填写域名所有者信息
5. 完成支付

域名选择建议: - ✅ 选择.com、.cn等常见后缀 - ✅ 域名简短易记 - ✅ 避免使用特殊字符 - ❌ 避免使用商标名称

1.2 购买服务器

推荐云服务商: - 阿里云:https://www.aliyun.com - 腾讯云:https://cloud.tencent.com - 华为云:https://www.huaweicloud.com

服务器配置建议

Text Only
CPU: 2核
内存: 2GB-4GB
硬盘: 40GB SSD
带宽: 3Mbps-5Mbps
操作系统: Ubuntu 20.04 LTS

购买步骤

Bash
# 登录云服务商控制台
# 选择"云服务器ECS" → "创建实例"
# 选择地域(建议选择离用户近的地域)
# 选择实例规格(2核4GB)
# 选择镜像(Ubuntu 20.04 LTS)
# 选择存储(40GB SSD)
# 选择带宽(3Mbps)
# 设置登录密码(记住这个密码!)
# 确认订单并支付


第二步:配置DNS解析

2.1 获取服务器公网IP

登录云服务器控制台,找到服务器的公网IP地址,例如:47.95.123.45

2.2 配置DNS解析记录

在域名注册商的DNS管理页面,添加以下记录:

Text Only
记录类型: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解析

Bash
# 在本地电脑执行
nslookup myblog.com
ping myblog.com

# 预期输出:
# myblog.com 的 IP 地址是 47.95.123.45

第三步:使用SSH连接服务器

3.1 获取服务器信息

从云服务商控制台获取: - 公网IP:47.95.123.45 - 用户名:root(Ubuntu默认) - 密码:购买时设置的密码

3.2 使用SSH连接

Windows用户

Bash
# 使用PowerShell或CMD
ssh root@47.95.123.45
# 输入密码

# 或者使用PuTTY等SSH客户端工具

Mac/Linux用户

Bash
ssh root@47.95.123.45
# 输入密码

配置SSH密钥登录(推荐)

Bash
# 在本地电脑生成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配置

Bash
# 编辑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

Bash
# 更新系统包
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 创建项目目录结构

Bash
# 创建项目目录
mkdir -p ~/myblog
cd ~/myblog

# 创建必要的目录
mkdir -p nginx/ssl
mkdir -p app
mkdir -p data

4.3 创建Docker Compose配置文件

创建 docker-compose.yml

YAML
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

Nginx Configuration File
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应用

Bash
# 进入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>关于我 &rarr;</h2>
            <p>了解更多关于我的信息</p>
          </a>
          <a href="/blog" className={styles.card}>
            <h2>博客文章 &rarr;</h2>
            <p>阅读我的技术文章</p>
          </a>
        </div>
      </main>
    </>
  )
}
EOF

4.6 启动服务

Bash
# 回到项目根目录
cd ~/myblog

# 启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

第五步:配置HTTPS证书

5.1 安装Certbot

Bash
# 安装Certbot
sudo apt install certbot -y

# 安装Certbot Nginx插件
sudo apt install python3-certbot-nginx -y

5.2 获取SSL证书

Bash
# 获取证书(自动配置Nginx)
sudo certbot --nginx -d myblog.com -d www.myblog.com

# 按提示操作:
# 1. 输入邮箱地址
# 2. 同意服务条款
# 3. 选择是否分享邮箱
# 4. 选择是否将HTTP重定向到HTTPS(选择2)

5.3 自动续期证书

Bash
# 测试自动续期
sudo certbot renew --dry-run

# Certbot会自动创建定时任务
# 查看定时任务
sudo systemctl list-timers | grep certbot

5.4 手动配置证书(可选)

如果自动配置失败,可以手动配置:

Bash
# 停止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控制台配置缓存规则:

Text Only
文件类型:.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:

JavaScript
// 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加速

Bash
# 查看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

服务器配置建议

Text Only
CPU: 1核
内存: 512MB-1GB
硬盘: 10GB-20GB
带宽: 1TB流量/月
操作系统: Ubuntu 20.04 LTS
价格: $5-$10/月

1.2 购买步骤

Bash
1. 注册账号并充值
2. 选择服务器地域(推荐:美国、日本、新加坡)
3. 选择服务器配置
4. 选择操作系统(Ubuntu 20.04 LTS)
5. 创建服务器
6. 记录服务器IP和密码

第二步:安装代理服务端

2.1 连接到VPS

Bash
# 使用SSH连接
ssh root@your-vps-ip
# 输入密码

# 更新系统
apt update && apt upgrade -y  # &&前一个成功才执行后一个;||前一个失败才执行

2.2 安装V2Ray服务端

Bash
# 下载并安装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

Bash
# 备份原配置
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作为反向代理:

Bash
# 安装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

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模式

Bash
# 查看虚拟网卡
# 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

JavaScript
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 测试基本连接

Bash
# 测试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 测试速度

Bash
# 测试下载速度
curl -o /dev/null https://speed.hetzner.de/100MB.bin

# 使用speedtest-cli
pip install speedtest-cli
speedtest-cli

6.3 测试DNS解析

Bash
# 查看DNS解析
nslookup www.google.com
nslookup www.github.com

# 应该解析到正确的IP地址

6.4 测试浏览器访问

  1. 打开浏览器
  2. 访问 https://www.google.com
  3. 访问 https://github.com
  4. 访问 https://www.youtube.com
  5. 检查是否能正常访问

📊 项目总结

完成的功能: ✅ 购买海外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 创建项目结构

Bash
# 创建项目目录
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

Docker
# 使用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

Text Only
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

Python
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

YAML
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

Text Only
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 启动服务

Bash
# 构建并启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f api

第三步:使用Nginx反向代理

3.1 创建Nginx配置文件

创建 nginx/nginx.conf

Nginx Configuration File
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证书

Bash
# 停止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管理页面,添加以下记录:

Text Only
记录类型:A
主机记录:api
记录值:your-server-ip
TTL:600

4.2 配置SSL证书自动续期

Bash
# 创建续期脚本
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访问权限

Python
# 创建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 上传模型文件

Python
# 创建上传脚本
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缓存规则

Text Only
文件类型:*
缓存时间:不缓存

URL参数:不忽略

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

第一步:模型服务架构设计

Text Only
┌─────────────────────────────────────────────────────────────┐
│                        客户端层                              │
│         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

Bash
# 创建虚拟环境
python -m venv vllm-env
source vllm-env/bin/activate

# 安装vLLM
pip install vllm

# 安装依赖
pip install fastapi uvicorn sse-starlette

2.2 创建模型服务

Python
# 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

Docker
# 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容器启动时执行的默认命令
Text Only
# 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 Configuration File
# 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

YAML
# 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

第五步:监控和日志

Python
# 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访问权限

Python
# 创建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 配置权限策略

创建自定义权限策略:

Text Only
{
  "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记录:

Text Only
记录类型:CNAME
主机记录:files
记录值:file-share-bucket.oss-cn-hangzhou.aliyuncs.com
TTL:600

3.3 验证域名解析

Bash
# 查看DNS解析
nslookup files.yourdomain.com

# 测试访问
curl -I https://files.yourdomain.com

第四步:设置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缓存规则

Text Only
文件类型:.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

Python
# 创建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

Bash
# 安装tcpdump
sudo apt update
sudo apt install tcpdump -y

# 验证安装
tcpdump --version

1.2 基本抓包命令

Bash
# 抓取所有网络包
sudo tcpdump -i any

# 抓取指定网卡
sudo tcpdump -i eth0

# 抓取指定数量的包
sudo tcpdump -c 100

# 保存到文件
sudo tcpdump -w capture.pcap

# 读取抓包文件
sudo tcpdump -r capture.pcap

1.3 高级抓包命令

Bash
# 抓取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 分析网络流量

Bash
# 统计流量
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配置文件中添加日志配置:

YAML
# Clash配置文件
log-level: info
secret: "your-secret-key"

# 日志文件路径
external-controller: 127.0.0.1:9090

2.2 查看Clash日志

Bash
# 查看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日志

Bash
# 统计连接数
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 安装监控工具

Bash
# 安装ifstat(网络流量监控)
sudo apt install ifstat -y

# 安装nethogs(进程网络使用)
sudo apt install nethogs -y

# 安装iftop(实时网络流量)
sudo apt install iftop -y

3.2 使用ifstat监控网络

Bash
# 实时监控网络流量
ifstat

# 每2秒更新一次,显示5次
ifstat -i eth0 2 5

# 显示所有网卡
ifstat -a

3.3 使用nethogs监控进程

Bash
# 监控所有进程的网络使用
sudo nethogs

# 监控指定网卡
sudo nethogs eth0

# 设置刷新间隔
sudo nethogs -d 1

3.4 使用iftop监控流量

Bash
# 启动iftop
sudo iftop

# 监控指定网卡
sudo iftop -i eth0

# 显示端口信息
sudo iftop -P

# 不解析主机名
sudo iftop -n

第四步:使用Prometheus+Grafana监控

4.1 安装Prometheus

Bash
# 创建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

Bash
# 下载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

YAML
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 启动监控服务

Bash
# 启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 访问Prometheus
# http://your-server-ip:9090

# 访问Grafana
# http://your-server-ip:3000
# 默认用户名密码:admin/admin

4.5 配置Grafana仪表板

  1. 登录Grafana(http://your-server-ip:3000
  2. 添加数据源:
  3. 点击"Configuration" → "Data Sources"
  4. 点击"Add data source"
  5. 选择"Prometheus"
  6. 配置URL:http://prometheus:9090
  7. 点击"Save & Test"
  8. 导入仪表板:
  9. 点击"+" → "Import"
  10. 输入仪表板ID:1860(Node Exporter Full)
  11. 点击"Load"
  12. 选择Prometheus数据源
  13. 点击"Import"

📊 项目总结

完成的功能: ✅ 使用tcpdump抓包分析网络流量 ✅ 配置Clash日志监控 ✅ 监控服务器网络状态 ✅ 使用Prometheus收集指标 ✅ 使用Grafana可视化展示

技术要点: - tcpdump提供强大的网络抓包能力 - Clash日志记录代理使用情况 - ifstat/nethogs/iftop监控网络流量 - Prometheus收集和存储监控指标 - Grafana可视化展示监控数据


🔧 故障排查指南

网络连接问题排查流程

1. 检查网络连接

Bash
# 检查本地网络
ping 8.8.8.8

# 检查DNS解析
nslookup www.google.com

# 检查端口连通性
telnet www.google.com 80

# 使用curl测试
curl -I https://www.google.com

2. 检查防火墙

Bash
# 检查防火墙状态
sudo ufw status

# 查看防火墙规则
sudo iptables -L -n

# 检查端口是否开放
sudo netstat -tlnp | grep 80

3. 检查路由

Bash
# 查看路由表
route -n

# 查看默认网关
ip route show default

# 追踪路由
traceroute www.google.com

DNS问题排查

1. 检查DNS配置

Bash
# 查看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缓存

Bash
# Linux清除DNS缓存
sudo systemd-resolve --flush-caches

# Mac清除DNS缓存
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

# Windows清除DNS缓存
ipconfig /flushdns

3. 检查DNS记录

Bash
# 查询A记录
dig A myblog.com

# 查询MX记录
dig MX myblog.com

# 查询TXT记录
dig TXT myblog.com

# 查询所有记录
dig ANY myblog.com

代理问题排查

1. 检查代理配置

Bash
# 检查环境变量
echo $HTTP_PROXY
echo $HTTPS_PROXY
echo $NO_PROXY

# 检查Clash配置
cat ~/.config/clash/config.yaml

# 检查Clash日志
tail -f ~/.config/clash/logs/clash.log

2. 测试代理连接

Bash
# 测试代理是否工作
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. 检查代理服务器

Bash
# 连接到VPS
ssh root@your-vps-ip

# 检查V2Ray状态
systemctl status v2ray

# 查看V2Ray日志
journalctl -u v2ray -f

# 检查端口监听
netstat -tlnp | grep 10086  # grep文本搜索:按模式匹配行

Docker网络问题排查

1. 检查Docker网络

Bash
# 查看Docker网络
docker network ls

# 查看网络详情
docker network inspect bridge

# 查看容器网络
docker inspect <container-name> | grep -A 10 Networks  # |管道:将前一命令的输出作为后一命令的输入

2. 检查容器连接

Bash
# 进入容器
docker exec -it <container-name> /bin/bash

# 测试网络连接
ping google.com
curl -I https://www.google.com

# 查看DNS配置
cat /etc/resolv.conf

3. 检查端口映射

Bash
# 查看端口映射
docker port <container-name>

# 查看容器日志
docker logs <container-name>

# 重启容器
docker restart <container-name>

💡 最佳实践

网络安全建议

1. 使用HTTPS

Nginx Configuration File
# 强制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. 配置安全头

Nginx Configuration File
# 安全头配置
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. 配置防火墙

Bash
# 启用防火墙
sudo ufw enable

# 允许SSH
sudo ufw allow 22

# 允许HTTP/HTTPS
sudo ufw allow 80
sudo ufw allow 443

# 查看防火墙状态
sudo ufw status

4. 使用SSH密钥认证

Bash
# 生成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 Configuration File
# 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. 配置缓存

Nginx Configuration File
# 静态资源缓存
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加速

Bash
# 配置CDN缓存规则
# 静态资源:30天
# HTML文件:1小时
# API响应:不缓存

# 使用CDN域名
https://cdn.yourdomain.com/static/logo.png

4. 优化数据库查询

Python
# 使用索引
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. 选择合适的服务器配置

Text Only
小型博客:
- CPU: 1核
- 内存: 1GB
- 带宽: 1Mbps
- 价格: $5/月

中型应用:
- CPU: 2核
- 内存: 4GB
- 带宽: 3Mbps
- 价格: $20/月

大型应用:
- CPU: 4核
- 内存: 8GB
- 带宽: 5Mbps
- 价格: $40/月

2. 使用对象存储

Bash
# 将静态文件存储到OSS
- 图片、视频等大文件
- 减少服务器存储压力
- 降低带宽成本

# 配置生命周期规则
- 30天后转换为低频存储
- 90天后转换为归档存储

3. 使用CDN节省带宽

Bash
# 配置CDN加速
- 减少服务器带宽使用
- 提升访问速度
- 降低成本

# 选择合适的CDN套餐
- 按流量计费:适合流量波动大的应用
- 按带宽计费:适合流量稳定的应用

4. 定期清理无用资源

Bash
# 清理Docker镜像
docker image prune -a

# 清理Docker容器
docker container prune

# 清理Docker卷
docker volume prune

# 清理日志文件
find /var/log -type f -name "*.log" -mtime +30 -delete

备份和容灾建议

1. 数据备份策略

Bash
# 数据库备份
# 每天自动备份
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. 配置自动备份

YAML
# 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. 配置监控告警

YAML
# 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. 配置灾难恢复

Bash
# 准备备用服务器
# 1. 购买备用VPS
# 2. 配置相同的环境
# 3. 定期同步数据
# 4. 配置DNS切换

# DNS切换脚本
cat > switch-dns.sh << 'EOF'
#!/bin/bash
# 切换DNS到备用服务器
# 更新DNS记录
# 通知相关人员
EOF

📝 总结

学习要点回顾

通过本章的实战案例,我们学习了:

  1. 域名和DNS
  2. 购买和配置域名
  3. DNS解析和配置
  4. CDN加速配置

  5. 服务器和SSH

  6. 购买和配置服务器
  7. SSH连接和密钥认证
  8. 服务器安全配置

  9. 代理和VPN

  10. 配置科学上网环境
  11. Clash客户端配置
  12. TUN模式和PAC规则

  13. Docker网络

  14. Docker容器化部署
  15. Docker网络配置
  16. Docker Compose编排

  17. 云服务和CDN

  18. OSS对象存储
  19. CDN加速配置
  20. 负载均衡和反向代理

  21. 网络监控

  22. tcpdump抓包分析
  23. Prometheus监控
  24. Grafana可视化

  25. 故障排查

  26. 网络连接问题排查
  27. DNS问题排查
  28. 代理问题排查
  29. Docker网络问题排查

实战技能提升

通过完成这些实战案例,你应该能够:

✅ 独立搭建完整的Web应用 ✅ 配置稳定的科学上网环境 ✅ 部署AI模型API服务 ✅ 搭建文件共享服务 ✅ 监控和分析网络流量 ✅ 排查常见网络问题

下一步学习建议

  1. 深入学习
  2. 学习更多网络协议(HTTP/2、HTTP/3)
  3. 学习负载均衡和高可用架构
  4. 学习网络安全和渗透测试

  5. 实践项目

  6. 搭建个人博客网站
  7. 部署自己的AI应用
  8. 搭建文件共享服务

  9. 持续优化

  10. 优化网络性能
  11. 提升安全性
  12. 降低成本

🎉 恭喜你!

你已经完成了网络学习的全部内容!从基础理论到实战应用,你已经掌握了网络技术的核心知识和实际应用能力。

继续学习,不断实践,你将成为网络技术专家! 🚀


文档版本:v1.0 最后更新:2026年1月 作者:AI学习创作团队