亚麻云之全球加速器——CloudFront(CDN)服务入门
本文作者: 封磊
Eclicktech SA | AWS Community Builder DevTool | AWS UGL | 亚马逊云科技云博主
阿里云&InfoQ&CSDN签约作者
前言
经过前四篇文章的学习,我们已经构建了一个相当完整的Web应用架构:EC2运行WordPress,RDS管理数据库,S3存储静态资源。但是,当你的网站开始面向全球用户时,会发现一个新的挑战:地理距离带来的访问延迟。
北京的用户访问部署在美国的服务器,需要跨越半个地球;欧洲用户下载存储在亚洲S3桶中的图片,速度慢得让人抓狂。今天,让我们请出"全球加速器"——Amazon CloudFront,让你的网站在世界任何角落都能飞速加载。
网络延迟的现实挑战
让我们先看看没有CDN时的访问情况:
# 测试从不同地区访问你的网站
# 美国用户访问(服务器在us-east-1)
curl -w "Time: %{time_total}s\n" -o /dev/null -s http://your-ec2-ip
# Time: 0.2s# 模拟欧洲用户访问
curl -w "Time: %{time_total}s\n" -o /dev/null -s http://your-ec2-ip
# Time: 1.5s# 模拟亚洲用户访问
curl -w "Time: %{time_total}s\n" -o /dev/null -s http://your-ec2-ip
# Time: 2.3s# S3文件访问延迟
curl -w "Time: %{time_total}s\n" -o /dev/null -s \https://my-wordpress-assets-20231201.s3.amazonaws.com/wp-content/uploads/2023/12/large-image.jpg
# Time: 3.1s (从亚洲访问)
延迟带来的问题
1. 用户体验差
- 页面加载时间超过3秒,用户流失率显著增加
- 图片、视频加载缓慢,影响内容消费
- 移动端用户对延迟更加敏感
2. SEO影响
- Google将页面加载速度作为排名因素
- 高延迟影响搜索引擎爬虫效率
- 用户跳出率增加,影响网站权重
3. 带宽成本
- 所有请求都回源到原始服务器
- 重复下载相同内容,浪费带宽
- 服务器负载增加,需要更高配置
什么是CDN?
CDN(Content Delivery Network,内容分发网络)是一个分布在全球各地的服务器网络,就像在世界各地开设"分店",让用户就近获取内容。
CDN工作原理
用户请求流程:1. 用户访问 www.yoursite.com/image.jpg
2. DNS解析指向最近的CDN边缘节点
3. 边缘节点检查是否有缓存├── 有缓存 → 直接返回(缓存命中)└── 无缓存 → 回源获取 → 缓存 → 返回用户
4. 后续相同请求直接从边缘节点返回
CloudFront的优势
1. 全球边缘网络
- 400+ 边缘节点,覆盖全球主要城市
- 智能路由,自动选择最优路径
- 与AWS骨干网深度集成
2. 多源站支持
- S3桶:静态内容分发
- EC2/ELB:动态内容加速
- 自定义源站:任何HTTP服务器
- 多源站组合:不同内容类型使用不同源站
3. 智能缓存
- 基于HTTP头的缓存策略
- 查询字符串和Cookie处理
- 实时内容失效
- 压缩和优化
4. 安全防护
- DDoS攻击防护
- SSL/TLS加密
- 访问控制和地理限制
- WAF集成
CloudFront核心概念
分配(Distribution)
CloudFront的基本单位,定义了内容分发的配置:
# 分配的基本信息
Distribution ID: E1234567890ABC
Domain Name: d1234567890abc.cloudfront.net
Status: Deployed
Price Class: Use All Edge Locations
源站(Origin)
内容的原始位置:
S3源站
# S3桶作为源站
Origin Domain: my-wordpress-assets-20231201.s3.amazonaws.com
Origin Path: /wp-content
Origin Access Control: Enabled
自定义源站
# EC2实例作为源站
Origin Domain: your-ec2-ip
Origin Path: /
Protocol: HTTP/HTTPS
Port: 80/443
行为(Behavior)
定义不同路径的缓存和处理规则:
# 默认行为(/*)
Path Pattern: *
Origin: EC2-Origin
Viewer Protocol Policy: Redirect HTTP to HTTPS
Cache Policy: Managed-CachingOptimized# 静态资源行为(/wp-content/*)
Path Pattern: /wp-content/*
Origin: S3-Origin
Viewer Protocol Policy: HTTPS Only
Cache Policy: Managed-CachingOptimizedForUncompressedObjects
实战案例:为WordPress网站配置CloudFront
让我们为之前搭建的WordPress网站配置CloudFront,实现全球加速。
步骤1:创建CloudFront分配
使用控制台创建
- 选择源站:
- 主源站:EC2实例(动态内容)
- 辅助源站:S3桶(静态资源)
- 默认缓存行为:
- 路径模式:
*
(所有请求) - 源站:EC2实例
- 查看器协议策略:重定向HTTP到HTTPS
- 缓存策略:CachingOptimized
- 路径模式:
- 其他缓存行为:
- 路径模式:
/wp-content/*
- 源站:S3桶
- 查看器协议策略:仅HTTPS
- 缓存策略:CachingOptimizedForUncompressedObjects
- 路径模式:
使用命令行创建
# 创建分配配置文件
cat > cloudfront-config.json << EOF
{"CallerReference": "wordpress-cdn-$(date +%s)","Comment": "WordPress CDN Distribution","DefaultRootObject": "index.php","Origins": {"Quantity": 2,"Items": [{"Id": "EC2-Origin","DomainName": "your-ec2-ip","CustomOriginConfig": {"HTTPPort": 80,"HTTPSPort": 443,"OriginProtocolPolicy": "http-only","OriginSslProtocols": {"Quantity": 1,"Items": ["TLSv1.2"]}}},{"Id": "S3-Origin","DomainName": "my-wordpress-assets-20231201.s3.amazonaws.com","S3OriginConfig": {"OriginAccessIdentity": ""}}]},"DefaultCacheBehavior": {"TargetOriginId": "EC2-Origin","ViewerProtocolPolicy": "redirect-to-https","MinTTL": 0,"ForwardedValues": {"QueryString": true,"Cookies": {"Forward": "all"},"Headers": {"Quantity": 1,"Items": ["Host"]}}},"CacheBehaviors": {"Quantity": 1,"Items": [{"PathPattern": "/wp-content/*","TargetOriginId": "S3-Origin","ViewerProtocolPolicy": "https-only","MinTTL": 86400,"ForwardedValues": {"QueryString": false,"Cookies": {"Forward": "none"}}}]},"Enabled": true,"PriceClass": "PriceClass_All"
}
EOF# 创建CloudFront分配
aws cloudfront create-distribution \--distribution-config file://cloudfront-config.json
步骤2:配置源站访问控制(OAC)
为S3源站配置访问控制,确保只有CloudFront可以访问:
# 创建源站访问控制
aws cloudfront create-origin-access-control \--origin-access-control-config '{"Name": "S3-WordPress-Assets-OAC","Description": "OAC for WordPress S3 assets","OriginAccessControlOriginType": "s3","SigningBehavior": "always","SigningProtocol": "sigv4"}'# 获取OAC ID
OAC_ID=$(aws cloudfront list-origin-access-controls \--query 'OriginAccessControlList.Items[?Name==`S3-WordPress-Assets-OAC`].Id' \--output text)# 更新S3桶策略,只允许CloudFront访问
cat > s3-cloudfront-policy.json << EOF
{"Version": "2012-10-17","Statement": [{"Sid": "AllowCloudFrontServicePrincipal","Effect": "Allow","Principal": {"Service": "cloudfront.amazonaws.com"},"Action": "s3:GetObject","Resource": "arn:aws:s3:::my-wordpress-assets-20231201/*","Condition": {"StringEquals": {"AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E1234567890ABC"}}}]
}
EOFaws s3api put-bucket-policy \--bucket my-wordpress-assets-20231201 \--policy file://s3-cloudfront-policy.json
步骤3:配置自定义域名和SSL证书
# 申请SSL证书(必须在us-east-1区域)
aws acm request-certificate \--domain-name www.yourdomain.com \--domain-name yourdomain.com \--validation-method DNS \--region us-east-1# 获取证书ARN
CERT_ARN=$(aws acm list-certificates \--region us-east-1 \--query 'CertificateSummaryList[?DomainName==`www.yourdomain.com`].CertificateArn' \--output text)# 更新CloudFront分配,添加自定义域名
aws cloudfront get-distribution-config \--id E1234567890ABC > current-config.json# 编辑配置文件,添加:
# "Aliases": {
# "Quantity": 2,
# "Items": ["www.yourdomain.com", "yourdomain.com"]
# },
# "ViewerCertificate": {
# "ACMCertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012",
# "SSLSupportMethod": "sni-only",
# "MinimumProtocolVersion": "TLSv1.2_2021"
# }# 更新分配
aws cloudfront update-distribution \--id E1234567890ABC \--distribution-config file://updated-config.json \--if-match ETAG_VALUE
步骤4:配置DNS解析
# 获取CloudFront域名
CLOUDFRONT_DOMAIN=$(aws cloudfront get-distribution \--id E1234567890ABC \--query 'Distribution.DomainName' \--output text)# 创建CNAME记录
aws route53 change-resource-record-sets \--hosted-zone-id Z123456789 \--change-batch '{"Changes": [{"Action": "CREATE","ResourceRecordSet": {"Name": "www.yourdomain.com","Type": "CNAME","TTL": 300,"ResourceRecords": [{"Value": "'$CLOUDFRONT_DOMAIN'"}]}}]}'
步骤5:测试CloudFront分配
# 等待分配部署完成(通常需要15-20分钟)
aws cloudfront get-distribution \--id E1234567890ABC \--query 'Distribution.Status'# 测试CloudFront访问
curl -I https://d1234567890abc.cloudfront.net# 测试自定义域名
curl -I https://www.yourdomain.com# 测试静态资源加速
curl -w "Time: %{time_total}s\n" -o /dev/null -s \https://www.yourdomain.com/wp-content/uploads/2023/12/image.jpg
缓存策略配置
理解缓存行为
CloudFront的缓存基于以下因素:
- URL路径
- 查询字符串
- HTTP头
- Cookies
# 查看缓存命中情况
curl -I https://www.yourdomain.com/wp-content/uploads/2023/12/image.jpg
# 查看响应头:
# X-Cache: Hit from cloudfront
# X-Amz-Cf-Pop: NRT57-C1
# X-Amz-Cf-Id: unique-request-id
配置缓存策略
静态资源缓存策略
# 为静态资源配置长期缓存
cat > static-cache-policy.json << EOF
{"Name": "StaticAssetsCaching","Comment": "Optimized caching for static assets","DefaultTTL": 86400,"MaxTTL": 31536000,"MinTTL": 0,"ParametersInCacheKeyAndForwardedToOrigin": {"EnableAcceptEncodingGzip": true,"EnableAcceptEncodingBrotli": true,"QueryStringsConfig": {"QueryStringBehavior": "none"},"HeadersConfig": {"HeaderBehavior": "none"},"CookiesConfig": {"CookieBehavior": "none"}}
}
EOFaws cloudfront create-cache-policy \--cache-policy-config file://static-cache-policy.json
动态内容缓存策略
# 为动态内容配置短期缓存
cat > dynamic-cache-policy.json << EOF
{"Name": "DynamicContentCaching","Comment": "Optimized caching for dynamic content","DefaultTTL": 0,"MaxTTL": 86400,"MinTTL": 0,"ParametersInCacheKeyAndForwardedToOrigin": {"EnableAcceptEncodingGzip": true,"EnableAcceptEncodingBrotli": true,"QueryStringsConfig": {"QueryStringBehavior": "all"},"HeadersConfig": {"HeaderBehavior": "whitelist","Headers": {"Quantity": 3,"Items": ["Host", "User-Agent", "Accept-Language"]}},"CookiesConfig": {"CookieBehavior": "all"}}
}
EOFaws cloudfront create-cache-policy \--cache-policy-config file://dynamic-cache-policy.json
缓存失效(Invalidation)
当源站内容更新时,需要清除CloudFront缓存:
# 创建失效请求
aws cloudfront create-invalidation \--distribution-id E1234567890ABC \--invalidation-batch '{"Paths": {"Quantity": 3,"Items": ["/wp-content/themes/mytheme/style.css","/wp-content/uploads/2023/12/*","/index.php"]},"CallerReference": "invalidation-'$(date +%s)'"}'# 查看失效状态
aws cloudfront list-invalidations \--distribution-id E1234567890ABC# 批量失效(谨慎使用,有费用)
aws cloudfront create-invalidation \--distribution-id E1234567890ABC \--invalidation-batch '{"Paths": {"Quantity": 1,"Items": ["/*"]},"CallerReference": "full-invalidation-'$(date +%s)'"}'
高级应用场景
多源站配置
为不同类型的内容配置不同的源站:
# API请求 -> ALB
# 静态资源 -> S3
# 用户上传内容 -> 另一个S3桶
# 视频内容 -> 专用媒体服务器cat > multi-origin-config.json << EOF
{"Origins": {"Quantity": 4,"Items": [{"Id": "API-Origin","DomainName": "api.yourdomain.com","CustomOriginConfig": {"HTTPPort": 80,"HTTPSPort": 443,"OriginProtocolPolicy": "https-only"}},{"Id": "Static-Origin","DomainName": "static-assets.s3.amazonaws.com","S3OriginConfig": {"OriginAccessIdentity": ""}},{"Id": "UserContent-Origin", "DomainName": "user-uploads.s3.amazonaws.com","S3OriginConfig": {"OriginAccessIdentity": ""}},{"Id": "Media-Origin","DomainName": "media.yourdomain.com","CustomOriginConfig": {"HTTPPort": 80,"HTTPSPort": 443,"OriginProtocolPolicy": "https-only"}}]},"CacheBehaviors": {"Quantity": 3,"Items": [{"PathPattern": "/api/*","TargetOriginId": "API-Origin","ViewerProtocolPolicy": "https-only","MinTTL": 0,"DefaultTTL": 0,"MaxTTL": 0},{"PathPattern": "/uploads/*","TargetOriginId": "UserContent-Origin","ViewerProtocolPolicy": "https-only","MinTTL": 86400,"DefaultTTL": 86400,"MaxTTL": 31536000},{"PathPattern": "/media/*","TargetOriginId": "Media-Origin","ViewerProtocolPolicy": "https-only","MinTTL": 3600,"DefaultTTL": 86400,"MaxTTL": 31536000}]}
}
EOF
A/B测试配置
使用Lambda@Edge实现A/B测试:
exports.handler = (event, context, callback) => {const request = event.Records[0].cf.request;const headers = request.headers;// 获取或生成用户IDlet userId = null;if (headers.cookie) {const cookies = headers.cookie[0].value;const userIdMatch = cookies.match(/userId=([^;]+)/);userId = userIdMatch ? userIdMatch[1] : null;}if (!userId) {userId = Math.random().toString(36).substring(7);}// 基于用户ID进行A/B分组const group = parseInt(userId.slice(-1), 16) % 2 === 0 ? 'A' : 'B';// 修改请求路径if (group === 'B' && request.uri === '/') {request.uri = '/index-b.html';}// 添加自定义头request.headers['x-ab-group'] = [{key: 'X-AB-Group', value: group}];callback(null, request);
};
边缘计算优化
// 图片自动优化
exports.handler = (event, context, callback) => {const request = event.Records[0].cf.request;const headers = request.headers;// 检查是否为图片请求if (request.uri.match(/\.(jpg|jpeg|png|webp)$/i)) {// 获取设备信息const userAgent = headers['user-agent'] ? headers['user-agent'][0].value : '';const isMobile = /Mobile|Android|iPhone/i.test(userAgent);// 检查WebP支持const acceptHeader = headers['accept'] ? headers['accept'][0].value : '';const supportsWebP = acceptHeader.includes('image/webp');// 修改请求参数let querystring = request.querystring || '';if (isMobile) {querystring += (querystring ? '&' : '') + 'w=800';}if (supportsWebP) {querystring += (querystring ? '&' : '') + 'format=webp';}request.querystring = querystring;}callback(null, request);
};
迁移验证清单
功能验证
- 网站通过CloudFront域名正常访问
- 自定义域名解析正确
- SSL证书配置正确,HTTPS访问正常
- 静态资源(CSS、JS、图片)正常加载
- 动态内容(WordPress管理后台)正常工作
- 表单提交和用户交互功能正常
性能验证
# 1. 测试全球访问速度
# 使用在线工具测试多地区访问速度
# 或使用curl测试
for region in us-east-1 eu-west-1 ap-southeast-1; doecho "Testing from $region:"time curl -o /dev/null -s https://www.yourdomain.com
done# 2. 检查缓存命中率
aws cloudwatch get-metric-statistics \--namespace AWS/CloudFront \--metric-name CacheHitRate \--dimensions Name=DistributionId,Value=E1234567890ABC \--start-time $(date -d '1 hour ago' -u +%Y-%m-%dT%H:%M:%SZ) \--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \--period 300 \--statistics Average# 3. 验证压缩效果
curl -H "Accept-Encoding: gzip" -I https://www.yourdomain.com/wp-content/themes/mytheme/style.css | grep -i content-encoding
安全验证
- HTTP自动重定向到HTTPS
- SSL证书有效且评级良好
- 源站访问控制正确配置
- 地理限制(如果配置)正常工作
- WAF规则(如果配置)正常工作
最佳实践总结
缓存策略
- 静态资源:长期缓存(1年),忽略查询参数和Cookie
- 动态内容:短期缓存(5-60分钟),转发必要的头和Cookie
- API接口:根据业务需求,可能不缓存或短期缓存
- 用户相关内容:不缓存或使用Vary头
安全配置
- 强制HTTPS:配置HTTP到HTTPS重定向
- 最新TLS版本:使用TLSv1.2或更高版本
- 源站保护:使用OAC限制直接访问S3
- 访问控制:根据需要配置地理限制和WAF
成本优化
- 合理选择价格等级:根据用户分布选择合适的边缘节点
- 优化缓存命中率:减少回源请求
- 压缩内容:启用Gzip和Brotli压缩
- 监控使用量:设置预算告警
监控运维
- 关键指标监控:请求量、缓存命中率、错误率、延迟
- 告警设置:异常情况及时通知
- 日志分析:定期分析访问模式和性能
- 定期优化:根据监控数据调整配置
下一步学习方向
掌握了CloudFront基础后,你可以继续探索:
- IAM权限管理:为CloudFront和相关服务配置精细权限(下一篇文章重点)
- AWS Shield:DDoS攻击防护
- AWS WAF:Web应用防火墙高级配置
- Lambda@Edge:边缘计算深入应用
- CloudFormation:基础设施即代码管理CDN
结语
通过配置CloudFront CDN,我们为网站装上了"全球加速器"。无论用户身在何处,都能享受到快速的访问体验。CloudFront不仅提升了性能,还增强了安全性,降低了源站负载。
从单一服务器到全球分布式架构,这是现代Web应用的必经之路。我们学会了:
- 理解CDN的工作原理和价值
- 配置多源站和缓存策略
- 实现SSL/TLS安全传输
- 使用边缘计算优化用户体验
- 监控和优化CDN性能
现在我们的架构已经相当完整:
- 计算层:EC2(动态内容)
- 数据层:RDS(数据库)
- 存储层:S3(静态资源)
- 加速层:CloudFront(全球CDN)
在下一篇文章中,我们将学习IAM权限管理,为整个架构配置安全的访问控制,确保每个组件都有合适的权限,既保证功能正常,又维护系统安全。
全球用户,本地速度!CloudFront让你的网站在世界任何角落都能飞速加载!