一、项目背景与需求分析
1.1 业务场景
为一家初创电商公司搭建线上平台,核心特点:
- 商品展示:图片密集型,需CDN加速
- 用户交易:订单、支付环节数据一致性要求高
- 促销活动:流量波动剧烈(日常1000并发,大促时10000+并发)
- 数据合规:用户隐私、交易数据需安全存储
1.2 技术指标
| 指标项 | 要求值 | 说明 |
|---|---|---|
| 日均PV | 10万+ | 页面浏览量 |
| 峰值并发 | 1000+ | 同时在线用户 |
| 可用性(SLA) | 99.9% | 年停机时间<8.76小时 |
| 平均响应时间 | <200ms | 首字节时间(TTFB) |
| P95响应时间 | <500ms | 95%请求在此时间内完成 |
| 月预算 | ≤500元 | 初创公司成本敏感 |
| 数据持久性 | 99.9999999% | 不能丢数据 |
1.3 架构设计原则
- 无单点故障 :任何一台服务器宕机不影响服务(领取新用户9折优惠)
- 水平扩展:流量增长时可通过加机器解决
- 成本最优:追求性价比最优配置
- 运维自动化:减少人工干预
二、云产品选型深度对比
2.1 计算层选型
| 对比项 | 云服务器(ECS) | 轻量应用服务器 | 函数计算(FC) |
|---|---|---|---|
| 适用场景 | 生产环境 | 个人博客/小型网站 | 事件驱动 |
| 配置灵活性 | 极高 | 低(固定套餐) | 无(自动扩缩) |
| 网络能力 | VPC专有网络 | 基础网络 | 自动分配 |
| 扩展能力 | 自动伸缩组 | 手动升级 | 自动无限扩展 |
| 2核4G月费 | ~120元(包年) | ~60元 | 按调用量 |
| 本案例选择 | ✅ 主选 | 开发测试环境 | 异步任务 |
选型结论:云服务器是生产环境标准选择,具备VPC隔离、负载均衡、自动伸缩等关键能力。
2.2 数据库层选型
| 对比项 | 自建MySQL | 托管数据库(RDS) | 云原生数据库 |
|---|---|---|---|
| 运维成本 | 高 | 低 | 极低 |
| 高可用 | 需自行搭建主从 | 自动主从+切换 | 多节点冗余 |
| 备份恢复 | 手动配置 | 自动备份7天 | 秒级备份 |
| 只读扩展 | 需自行搭建 | 一键添加只读实例 | 自动扩展 |
| 2核4G价格 | ~120元/月 | ~200元/月 | ~300元/月 |
| 本案例选择 | ❌ | ✅ 主选 | 预算充足时升级 |
2.3 存储层选型
| 对比项 | 本地磁盘 | 对象存储(OSS) | 文件存储(NAS) |
|---|---|---|---|
| 容量上限 | 受磁盘限制 | 无限 | 无限 |
| CDN加速 | ❌ | ✅ 原生支持 | ❌ |
| 图片处理 | ❌ | ✅ 内置服务 | ❌ |
| 100GB/月成本 | ~40元 | ~11元 | ~30元 |
| 本案例选择 | 系统盘 | ✅ 主选 | 共享配置 |
2.4 网络层选型
| 对比项 | 自建Nginx | 负载均衡(SLB) |
|---|---|---|
| 高可用 | 单点故障风险 | 多可用区冗余 |
| 健康检查 | 需自行配置 | 内置多种检查 |
| SSL证书 | 手动配置 | 支持自动HTTPS |
| DDoS防护 | 需额外购买 | 基础5Gbps免费 |
| 月费 | ~120元 | ~15元 |
| 本案例选择 | ❌ | ✅ 必选 |
三、完整架构设计
3.1 架构全景图
┌─────────────────────────────────────────────────────────────┐
│ 用户请求层 │
│ 移动端App PC浏览器 小程序 │
└──────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 流量接入层 │
│ CDN(全站加速) │
│ • 静态资源缓存(图片/CSS/JS) │
│ • 动态内容加速(API接口) │
│ • HTTPS证书管理 │
└──────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 负载均衡层 │
│ 应用型负载均衡(SLB) │
│ • 多可用区部署(可用区A + 可用区B) │
│ • 会话保持(基于Cookie) │
│ • 健康检查:HTTP /health 每2秒 │
│ • 转发策略:80 → 服务器:3000 │
└──────────────┬─────────────────────────────┬────────────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ 服务器实例-1 │ │ 服务器实例-2 │
│ (可用区A) │◄────────►│ (可用区B) │
│ • 2核4G │ 内网 │ • 2核4G │
│ • Node.js 18 │ 互通 │ • Node.js 18 │
│ • Nginx反向代理 │ │ • Nginx反向代理 │
│ • PM2进程管理 │ │ • PM2进程管理 │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
└──────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 数据存储层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 托管数据库 │ │ 云Redis │ │ 对象存储 │ │
│ │ • 主实例 │ │ • 热点缓存 │ │ • 商品图片 │ │
│ │ • 只读实例 │ │ • Session │ │ • 用户上传 │ │
│ │ • 自动备份 │ │ • 限频计数 │ │ • 静态资源 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 监控运维层 │
│ ┌──────────┐ ┌──────────┐ ┌────────────────────────┐ │
│ │ 云监控 │ │ 日志服务 │ │ 云安全中心 │ │
│ │ • CPU/内存│ │ • 应用日志 │ │ • 漏洞扫描 │ │
│ │ • 网络 │ │ • 访问日志 │ │ • 基线检查 │ │
│ │ • 告警 │ │ • 错误分析 │ │ • 异常登录检测 │ │
│ └──────────┘ └──────────┘ └────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.2 高可用设计要点
- 跨可用区部署:服务器分布在两个可用区,任一可用区故障服务不中断
- 数据库主从架构:自动主从复制,故障时自动切换,RPO=0
- 无状态应用:Session存入Redis,任何服务器宕机用户请求可无缝切换
- 对象存储多冗余:数据自动存储3份,单份损坏自动修复
四、详细实施步骤
步骤一:购买和配置云服务器
1.1 选择实例规格
| 规格族 | 适用场景 | 2核4G月费 | 性能特点 | 本案例选择 |
|---|---|---|---|---|
| 共享标准型 s6 | 轻量级Web应用 | ~120元 | 性价比高,CPU突发性能 | ✅ |
| 计算型 c7 | 计算密集型 | ~200元 | CPU性能稳定 | 预算充足时升级 |
| 通用型 g7 | 通用场景 | ~180元 | CPU/内存均衡 | 备选 |
| 突发性能实例 t6 | 开发测试 | ~60元 | CPU有性能积分限制 | ❌ 生产不推荐 |
选择s6的理由:Web应用非CPU密集型,突发性能足以应对日常流量。
1.2 购买建议
- 计费方式:包年包月,1年期(比按量节省~35%)
- 地域选择:离目标用户最近的地域(如华东选杭州)
- 网络类型 :必须选择专有网络VPC
- 安全组:先放行22(SSH)、80(HTTP)、443(HTTPS)
1.3 系统初始化脚本(两台服务器均执行)
bash
#!/bin/bash
# init_server.sh - 服务器系统初始化脚本
set -e
echo "=== 开始系统初始化 ==="
# 1. 更新系统
yum update -y
# 2. 安装基础工具
yum install -y vim git wget curl net-tools htop
# 3. 配置时区
timedatectl set-timezone Asia/Shanghai
# 4. 优化内核参数(高并发场景)
cat >> /etc/sysctl.conf << 'EOF'
# 网络优化
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 10000 65000
# 内存优化
vm.swappiness = 10
vm.overcommit_memory = 1
EOF
sysctl -p
# 5. 增大文件描述符限制
cat >> /etc/security/limits.conf << 'EOF'
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
EOF
# 6. 关闭firewalld(云安全组已处理)
systemctl stop firewalld
systemctl disable firewalld
# 7. 安装Node.js 18
curl -fsSL https://rpm.nodesource.com/setup_18.x | bash -
yum install -y nodejs
node --version
npm --version
# 8. 安装PM2进程管理器
npm install -g pm2
pm2 --version
# 9. 安装Nginx
yum install -y nginx
systemctl start nginx
systemctl enable nginx
# 10. 创建应用目录
mkdir -p /var/www/app
mkdir -p /var/log/app
chown -R nginx:nginx /var/www/app
echo "=== 系统初始化完成 ==="
步骤二:部署应用环境
2.1 应用代码结构
/var/www/app/
├── app.js # 主应用入口
├── package.json # 依赖配置
├── ecosystem.config.js # PM2配置
├── routes/ # 路由目录
├── models/ # 数据模型
├── middleware/ # 中间件
└── public/ # 静态文件(生产环境建议放OSS)
2.2 Node.js应用示例(app.js)
javascript
const express = require('express');
const redis = require('redis');
const mysql = require('mysql2/promise');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;
// 健康检查端点(负载均衡用)
app.get('/health', (req, res) => {
res.status(200).json({
status: 'ok',
timestamp: new Date().toISOString(),
server: process.env.HOSTNAME || 'unknown'
});
});
// 数据库连接池配置
const dbConfig = {
host: process.env.DB_HOST || 'your-rds-endpoint.mysql.rds.aliyuncs.com',
user: process.env.DB_USER || 'app_user',
password: process.env.DB_PASSWORD || 'your_password',
database: process.env.DB_NAME || 'ecommerce',
port: 3306,
connectionLimit: 20,
acquireTimeout: 60000,
timeout: 60000
};
const pool = mysql.createPool(dbConfig);
// Redis连接
const redisClient = redis.createClient({
host: process.env.REDIS_HOST || 'your-redis-endpoint.redis.rds.aliyuncs.com',
port: 6379,
password: process.env.REDIS_PASSWORD || 'your_redis_password'
});
redisClient.on('error', (err) => console.error('Redis Error:', err));
// 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// API路由示例:商品列表(带缓存)
app.get('/api/products', async (req, res) => {
try {
// 先查Redis缓存
const cacheKey = 'products:list';
const cached = await redisClient.get(cacheKey);
if (cached) {
return res.json({ source: 'cache', data: JSON.parse(cached) });
}
// 缓存未命中,查数据库
const [rows] = await pool.execute(
'SELECT id, name, price, image_url FROM products WHERE status = 1 LIMIT 50'
);
// 写入缓存(TTL 60秒)
await redisClient.setex(cacheKey, 60, JSON.stringify(rows));
res.json({ source: 'database', data: rows });
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// 静态文件(开发环境,生产用OSS+CDN)
app.use('/static', express.static(path.join(__dirname, 'public')));
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`Server running on port ${PORT}`);
});
2.3 PM2配置文件(ecosystem.config.js)
javascript
module.exports = {
apps: [{
name: 'ecommerce-app',
script: './app.js',
instances: 'max', // 使用所有CPU核心
exec_mode: 'cluster', // 集群模式
env: {
NODE_ENV: 'production',
PORT: 3000
},
// 日志配置
log_file: '/var/log/app/combined.log',
out_file: '/var/log/app/out.log',
error_file: '/var/log/app/error.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
// 内存限制(超过自动重启)
max_memory_restart: '1G',
// 自动重启策略
min_uptime: '10s',
max_restarts: 5,
// 优雅重启
kill_timeout: 5000,
listen_timeout: 10000
}]
};
启动命令:
bash
cd /var/www/app
pm2 start ecosystem.config.js
pm2 save
pm2 startup systemd
2.4 Nginx反向代理配置
nginx
# /etc/nginx/conf.d/app.conf
upstream app_servers {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 80;
server_name your-domain.com www.your-domain.com;
# 安全响应头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 日志格式
log_format app_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/app_access.log app_log;
error_log /var/log/nginx/app_error.log warn;
# Gzip压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 1000;
# 静态文件(fallback)
location /static/ {
alias /var/www/app/public/;
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}
# 健康检查端点
location /health {
proxy_pass http://app_servers;
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_connect_timeout 2s;
proxy_send_timeout 2s;
proxy_read_timeout 2s;
}
# API和动态请求
location / {
proxy_pass http://app_servers;
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_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
# API限流(防CC攻击)
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://app_servers;
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;
}
}
测试并重载Nginx:
bash
nginx -t
systemctl reload nginx
步骤三:配置高可用架构
3.1 负载均衡配置
在云平台控制台创建应用型负载均衡(ALB):
基础配置:
- 地域:与服务器相同(如华东1)
- 网络类型:专有网络VPC
- 实例类型:共享型
- 协议:HTTP/HTTPS
后端服务器组:
- 添加服务器-1(可用区A)和服务器-2(可用区B)
- 端口:80
- 权重:各50(平均分配)
健康检查:
- 协议:HTTP
- 检查路径:
/health - 响应超时:5秒
- 健康阈值:2次
- 不健康阈值:3次
- 检查间隔:2秒
会话保持:
- 方式:植入Cookie(Cookie名:
ALB_COOKIE) - 超时:3600秒
3.2 托管数据库配置
创建实例:
- 引擎:MySQL 8.0
- 版本:高可用版(自动主备)
- 规格:2核4GB
- 存储:100GB SSD云盘
- 网络:VPC(与服务器同一VPC)
安全设置:
- 白名单:仅允许服务器所在安全组访问
- 禁止公网访问
账号创建:
- 创建应用专用账号(非root)
- 权限:仅授予必要的数据库权限
自动备份:
- 备份周期:每天
- 保留时间:7天
- 备份时间:凌晨2:00-5:00
只读实例(可选,用于报表查询):
- 规格:1核2GB
- 延迟阈值:30秒
3.3 对象存储配置
创建Bucket:
- 名称:
your-app-static-assets(全局唯一) - 地域:与服务器相同
- 存储类型:标准存储
- 读写权限:公共读
CDN加速配置:
- 绑定自定义域名:
static.your-domain.com - 开启HTTPS
- 缓存规则:
- 图片文件(.jpg/.png/.gif):缓存365天
- CSS/JS文件:缓存30天
- HTML文件:不缓存
图片处理服务:
- 开启图片缩放、水印、格式转换
- 示例:
image.jpg?x-oss-process=image/resize,w_300自动返回300px宽度
生命周期规则:
- 30天后转低频访问(节省40%)
- 180天后转归档存储(节省70%)
3.4 云数据库Redis配置
创建实例:
- 架构:标准版-单副本(缓存数据可重建)
- 规格:1GB
- 网络:VPC
安全设置:
- 白名单:仅服务器安全组
- 密码:强密码,定期更换
使用场景:
- Session存储(替代应用服务器本地存储)
- 热点数据缓存(商品列表、配置信息)
- 限频计数(API防刷)
- 分布式锁
步骤四:安全加固
4.1 安全组规则(最小权限原则)
| 方向 | 协议 | 端口 | 授权对象 | 说明 |
|---|---|---|---|---|
| 入方向 | TCP | 22 | 你的办公IP/32 | SSH仅允许办公网络 |
| 入方向 | TCP | 80 | 0.0.0.0/0 | HTTP公网访问 |
| 入方向 | TCP | 443 | 0.0.0.0/0 | HTTPS公网访问 |
| 入方向 | TCP | 3000 | 负载均衡安全组 | 仅允许负载均衡访问 |
| 出方向 | ALL | ALL | 0.0.0.0/0 | 允许所有出站 |
禁止:
- 3306(MySQL)公网暴露
- 6379(Redis)公网暴露
4.2 SSL证书配置(HTTPS)
使用云平台免费DV证书:
nginx
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/nginx/ssl/your-domain.crt;
ssl_certificate_key /etc/nginx/ssl/your-domain.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
# HTTP强制跳转HTTPS
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
五、成本深度分析与优化
5.1 完整成本清单
| 产品 | 配置 | 优化前月费 | 优化后月费 | 优化手段 |
|---|---|---|---|---|
| 云服务器 × 2 | 2核4G | 480元 | 156元 | 包年+预留实例 |
| 托管数据库 | 2核4G | 280元 | 180元 | 包年包月 |
| 负载均衡 | 共享型 | 25元 | 15元 | 固定费用 |
| 对象存储 | 100GB | 50元 | 11元 | 生命周期管理 |
| CDN | 100GB流量 | 100元 | 40元 | 流量包 |
| Redis | 1GB | 80元 | 50元 | 包年包月 |
| 带宽 | 5Mbps | 125元 | 40元 | 按使用流量 |
| 云监控 | 基础版 | 0元 | 0元 | 免费 |
| SSL证书 | DV证书 | 0元 | 0元 | 免费 |
| 合计 | 1140元 | 492元 | 节省56.8% |
5.2 优化策略详解
策略1:预留实例券(节省35%)
| 购买方式 | 1年费用 | 月均 | 节省 |
|---|---|---|---|
| 按量付费 | 2880元 | 240元 | - |
| 包年包月 | 1872元 | 156元 | 35% |
| 预留实例券 | 1728元 | 144元 | 40% |
策略2:对象存储生命周期(节省40%)
| 存储类型 | 单价(元/GB/月) | 适用场景 |
|---|---|---|
| 标准存储 | 0.12 | 频繁访问 |
| 低频访问 | 0.08 | 月均访问<1次 |
| 归档存储 | 0.033 | 很少访问 |
| 冷归档 | 0.015 | 几乎不访问 |
策略3:CDN流量包(节省60%)
- 按量计费(带宽):~100元/100GB
- 流量包(100GB):~40元
策略4:按使用流量计费(节省60%)
- 固定带宽5Mbps:125元/月
- 按使用流量(100GB):~40元/月
六、性能测试与调优
6.1 压力测试方案
| 测试工具 | 测试场景 | 并发数 | 持续时间 |
|---|---|---|---|
| wrk | 商品列表API | 1000 | 10分钟 |
| PTS | 完整下单流程 | 500 | 30分钟 |
| PTS | 突发流量模拟 | 0→5000 | 5分钟 |
6.2 关键测试结果
单台 vs 负载均衡(2台)
| 指标 | 单台服务器 | 负载均衡(2台) | 提升 |
|---|---|---|---|
| QPS | 850 | 1,680 | +97% |
| 平均响应时间 | 230ms | 118ms | -49% |
| P95响应时间 | 450ms | 215ms | -52% |
| 错误率 | 0.5% | 0.08% | -84% |
| CPU峰值 | 95% | 48% | -49% |
启用Redis缓存前后
| 指标 | 无缓存 | 有Redis缓存 | 提升 |
|---|---|---|---|
| 商品列表API响应 | 180ms | 25ms | -86% |
| 数据库QPS | 2,000 | 300 | -85% |
| 数据库CPU | 78% | 15% | -81% |
6.3 MySQL调优参数
sql
-- 连接数优化
SET GLOBAL max_connections = 500;
SET GLOBAL max_connect_errors = 1000;
-- InnoDB缓冲池(设为内存的70%)
SET GLOBAL innodb_buffer_pool_size = 2684354560; -- 2.5GB
-- 慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
-- 连接超时
SET GLOBAL wait_timeout = 600;
SET GLOBAL interactive_timeout = 600;
七、监控与告警体系
7.1 关键告警规则
| 监控项 | 告警条件 | 通知方式 | 级别 |
|---|---|---|---|
| CPU使用率 | >80% 持续5分钟 | 短信+邮件 | 警告 |
| CPU使用率 | >95% 持续3分钟 | 电话+短信 | 紧急 |
| 内存使用率 | >85% 持续5分钟 | 短信+邮件 | 警告 |
| 磁盘使用率 | >85% 持续10分钟 | 短信+邮件 | 警告 |
| 数据库CPU | >70% 持续5分钟 | 短信+邮件 | 警告 |
| 负载均衡健康状态 | 健康实例<2 | 电话+短信 | 紧急 |
| CDN命中率 | <85% 持续10分钟 | 邮件 | 警告 |
7.2 自动化健康检查脚本
bash
#!/bin/bash
# health_check.sh - 综合健康检查
LOG_FILE="/var/log/health_check.log"
ALERT_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
send_alert() {
local message="$1"
curl -s -X POST "$ALERT_WEBHOOK" \
-H "Content-Type: application/json" \
-d "{\"msgtype\": \"text\", \"text\": {\"content\": \"$message\"}}" > /dev/null
}
check_service() {
local service=$1
if systemctl is-active --quiet $service; then
log "✅ $service 运行正常"
return 0
else
log "❌ $service 服务异常"
send_alert "【告警】$(hostname) $service 服务异常!"
return 1
fi
}
check_disk() {
local usage=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $usage -gt 90 ]; then
log "❌ 磁盘使用率过高: ${usage}%"
send_alert "【紧急】$(hostname) 磁盘使用率 ${usage}%!"
return 1
else
log "✅ 磁盘使用率: ${usage}%"
return 0
fi
}
check_app_health() {
local response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/health)
if [ "$response" == "200" ]; then
log "✅ 应用健康检查通过"
return 0
else
log "❌ 应用健康检查失败: HTTP $response"
send_alert "【紧急】$(hostname) 应用健康检查失败!"
return 1
fi
}
# 主逻辑
log "========== 开始健康检查 =========="
check_service nginx
check_service pm2-root
check_disk
check_app_health
log "========== 检查完成 =========="
添加到定时任务(每5分钟):
bash
crontab -e
# 添加:
*/5 * * * * /usr/local/bin/health_check.sh
八、故障处理与应急预案
8.1 常见故障处理
场景1:突发流量导致服务不可用
- 临时升级服务器配置(2核4G → 4核8G)
- 开启CDN全站加速,减轻源站压力
- 增加数据库只读实例
- Nginx开启限流:
limit_req zone=api_limit burst=10 nodelay
场景2:数据库连接池耗尽
bash
# 检查最大连接数
SHOW VARIABLES LIKE 'max_connections';
# 临时增加
SET GLOBAL max_connections = 1000;
场景3:磁盘空间不足
bash
# 定位大文件
du -sh /var/log/* | sort -rh | head -10
# 配置日志轮转
cat > /etc/logrotate.d/app << 'EOF'
/var/log/app/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 nginx nginx
}
EOF
8.2 数据备份策略
| 备份对象 | 备份方式 | 频率 | 保留时间 | 存储位置 |
|---|---|---|---|---|
| 应用代码 | Git仓库 | 每次提交 | 永久 | GitHub/GitLab |
| 数据库 | 自动备份 | 每天 | 7天 | 对象存储 |
| 数据库 | 手动逻辑备份 | 每周 | 30天 | 本地+OSS |
| 系统盘 | 快照 | 每周 | 4个 | 云平台 |
| 应用日志 | 日志服务 | 实时 | 30天 | 日志服务 |
九、总结与进阶建议
9.1 架构总结
通过本文的实战,我们用不到500元/月的成本,搭建了一套:
- ✅ 高可用:跨可用区部署,单点故障自动切换
- ✅ 高性能:QPS 1600+,平均响应<120ms
- ✅ 高安全:HTTPS加密、安全组隔离、漏洞扫描
- ✅ 可扩展:水平扩展只需增加服务器实例
- ✅ 可监控:全链路监控,异常自动告警
9.2 进阶优化方向
- 应用层:升级至计算型实例,或扩容至4台服务器
- 数据库层:升级至云原生数据库(自动读写分离)
- 缓存层:Redis升级至集群版
- 架构层:引入Kubernetes容器服务
- 安全层:接入Web应用防火墙(WAF)
9.3 给开发者的建议
- 从小开始:不要过度设计,本架构可支撑日活10万用户
- 监控先行:上线第一天就配置好监控和告警
- 自动化一切:部署、备份、监控都要脚本化
- 定期复盘:每月回顾成本和性能,及时调整配置
关于本文:所有技术方案均基于真实项目实践,遵循"简单可扩展"原则,避免过度工程化,同时确保生产环境所需的稳定性和安全性。