AWS-S3-CloudFront-ALB实战
1. 架构
用户
↓
Route 53 (DNS)
↓
CloudFront (CDN)
↓
├── S3 (静态文件)
└── ALB → EC2 / ECS / Lambda (动态)
2. S3 静态托管
2.1 创建 bucket
aws s3 mb s3://my-frontend --region us-east-1
# 关闭公开访问限制(如果要公开)
aws s3api delete-public-access-block --bucket my-frontend
2.2 上传 + 缓存头
# JS / CSS 长缓存
aws s3 sync ./dist/assets s3://my-frontend/assets/ \
--cache-control "public, max-age=31536000, immutable"
# HTML 不缓存
aws s3 cp ./dist/index.html s3://my-frontend/index.html \
--cache-control "no-cache"
# 全量同步并删除多余
aws s3 sync ./dist s3://my-frontend/ --delete
2.3 Bucket Policy(CloudFront OAC 访问)
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "cloudfront.amazonaws.com" },
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-frontend/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::123456789:distribution/E123ABC"
}
}
}]
}
S3 不直接公开 → CloudFront 通过 OAC(Origin Access Control)访问 → 用户只能通过 CloudFront。
3. CloudFront
3.1 Distribution 配置
控制台 → CloudFront → Create distribution:
- Origin:S3 bucket 选刚才的
- Origin access:Origin access control(OAC)
- Viewer protocol policy:Redirect HTTP to HTTPS
- Allowed HTTP methods:GET, HEAD, OPTIONS
- Cache policy:CachingOptimized(自动)
- Compress:Yes
- Price class:100(仅北美 + 欧洲,便宜)
3.2 缓存行为
按路径定不同策略:
/api/* → Origin: ALB cache-policy: CachingDisabled
/_next/* → Origin: S3 cache-policy: CachingOptimized
/* (default) → Origin: S3 cache-policy: CachingOptimized
3.3 自定义错误页
SPA fallback:
- HTTP error code: 403 / 404
- Response page path:
/index.html - HTTP response code: 200
3.4 失效(Invalidation)
aws cloudfront create-invalidation \
--distribution-id E123ABC \
--paths "/index.html" "/"
每月前 1000 路径免费,超出收费。
3.5 自定义域名
CloudFront → Alternate domain names → 加 app.example.com。
关联 ACM 证书(必须 us-east-1 region 的证书)。
Route 53 加 ALIAS 记录指向 CloudFront。
4. ACM(证书)
# 申请证书
aws acm request-certificate \
--domain-name "*.example.com" \
--validation-method DNS \
--subject-alternative-names "example.com" \
--region us-east-1
# DNS 验证(按提示加 CNAME)
ACM 自动续期。CloudFront 必须用 us-east-1 区域的证书。
5. ALB(应用负载均衡)
5.1 创建
aws elbv2 create-load-balancer \
--name prod-alb \
--subnets subnet-aaa subnet-bbb \
--security-groups sg-xxx \
--type application
跨 AZ 高可用。
5.2 Target Group
后端 EC2 / Container:
aws elbv2 create-target-group \
--name app-tg \
--protocol HTTP --port 8080 \
--vpc-id vpc-xxx \
--health-check-path /health \
--health-check-interval-seconds 30 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 3
5.3 Listener 与规则
HTTPS:443 → 默认 → forward 到 app-tg
路径规则:
/api/* → forward 到 api-tg
/admin/* → forward 到 admin-tg
Host = old.example.com → redirect 301
6. EC2 部署
# 启动实例
aws ec2 run-instances \
--image-id ami-xxx \
--instance-type t3.medium \
--key-name my-key \
--subnet-id subnet-aaa \
--security-group-ids sg-xxx \
--user-data file://cloud-init.sh
cloud-init.sh:
#!/bin/bash
apt update
apt install -y nginx nodejs npm
# 部署应用...
7. ECS / Fargate
容器化部署,比 EC2 更现代:
- ECS EC2 模式:跑在 EC2 上
- ECS Fargate:无服务器,按 vCPU/内存计费
# task-definition.json
{
"family": "frontend",
"networkMode": "awsvpc",
"containerDefinitions": [{
"name": "web",
"image": "ghcr.io/myorg/frontend:v1.0.0",
"portMappings": [{ "containerPort": 80 }],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/frontend",
"awslogs-region": "us-east-1"
}
}
}],
"cpu": "512",
"memory": "1024"
}
8. Route 53
8.1 ALIAS 记录
# 指向 CloudFront
aws route53 change-resource-record-sets --hosted-zone-id ZONE_ID --change-batch '{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "app.example.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "d111111abcdef8.cloudfront.net",
"EvaluateTargetHealth": false
}
}
}]
}'
ALIAS 是 AWS 专有,类似 CNAME 但根域可用且免费。
8.2 Health Check
定期探测后端,故障时 DNS 切到备份:
aws route53 create-health-check --health-check-config '{
"Type": "HTTPS",
"ResourcePath": "/health",
"FullyQualifiedDomainName": "app.example.com",
"Port": 443,
"RequestInterval": 30
}'
9. 成本控制
- CloudFront Price Class(地区受限版本便宜)
- S3 Lifecycle:旧文件转 IA / Glacier
- EC2 reserved instance(包年省 50%+)
- ALB 按小时 + LCU 计费,闲置删
- Lambda / Fargate 按需付费
- 设置 budget 告警
10. 常见反模式
- S3 公开读 + 暴露 bucket URL:不走 CloudFront 缓存
- CloudFront 证书没在 us-east-1:用不了
- ALB 无 health check:流量发到挂的实例
- 没设 CloudFront 失效策略:每次发版要等 24h 才生效
- S3 没开版本控制:误删无法恢复
- 没限制 IAM 权限:实例被入侵 = AWS 账户沦陷
- 跨 region 流量:账单飙升
- 不监控账单:突发费用月底才发现