本文作者: 封磊
Eclicktech SA | AWS Community Builder DevTool | AWS UGL | 亚马逊云科技云博主
阿里云&InfoQ&CSDN签约作者
前言
经过前三篇文章的学习,我们已经从Lightsail入门,掌握了EC2的灵活部署,并将数据库迁移到了RDS。现在我们的WordPress网站运行在EC2上,数据安全地存储在RDS中。但是,随着网站内容的增加,你可能会发现一个新的问题:服务器存储空间不够用了!
图片、视频、CSS、JavaScript文件越来越多,不仅占用服务器空间,还影响网站加载速度。今天,让我们为这些静态资源找一个更好的"家"——Amazon S3(Simple Storage Service)。
传统存储方式的局限
还记得我们在EC2上存储WordPress文件的方式吗?所有内容都堆在一个服务器上:
# 查看WordPress目录结构
ls -la /var/www/html/
drwxr-xr-x 5 apache apache 4096 Dec 1 10:00 wp-content
drwxr-xr-x 2 apache apache 4096 Dec 1 10:00 wp-includes
drwxr-xr-x 2 apache apache 4096 Dec 1 10:00 wp-admin
# wp-content目录越来越大
du -sh /var/www/html/wp-content/
2.5G /var/www/html/wp-content/
存在的问题
1. 存储空间限制
- EBS卷容量有限,扩展需要停机
- 大量媒体文件占用宝贵的服务器空间
- 备份整个服务器变得缓慢且昂贵
2. 性能影响
- 静态文件请求占用服务器带宽
- 影响动态内容的响应速度
- 单点访问,无法分布式加速
3. 可靠性风险
- 服务器故障可能导致所有文件丢失
- 备份恢复复杂,容易出错
- 无法实现异地容灾
4. 成本问题
- 需要为不常访问的文件支付高性能存储费用
- 带宽成本随文件访问量线性增长
- 无法根据访问频率优化存储成本
什么是Amazon S3?
Amazon S3是AWS提供的对象存储服务,可以理解为云端的"超级硬盘",但它比传统硬盘强大得多。
S3的核心概念
对象存储 vs 文件系统
# 传统文件系统(层级结构)
/var/www/html/
├── wp-content/
│ ├── uploads/
│ │ ├── 2023/
│ │ │ ├── 12/
│ │ │ │ └── image.jpg
│ │ └── themes/
│ └── plugins/
# S3对象存储(扁平结构,用键值对)
Bucket: my-wordpress-assets
Key: wp-content/uploads/2023/12/image.jpg
Key: wp-content/themes/mytheme/style.css
Key: wp-content/plugins/myplugin/script.js
桶(Bucket)
- 存储对象的容器,类似于顶级文件夹
- 全球唯一命名
- 可以设置访问权限和策略
对象(Object)
- 存储的文件和元数据
- 每个对象有唯一的键(Key)
- 大小可达5TB
S3的强大优势
1. 无限扩展
- 存储容量无限制
- 自动扩展,无需人工干预
- 按实际使用量付费
2. 高可用性
- 99.999999999%(11个9)的数据持久性
- 自动跨多个设施复制
- 区域性故障自动恢复
3. 多种存储类别
- 根据访问频率选择不同存储类别
- 自动生命周期管理
- 显著降低存储成本
4. 全球访问
- 通过HTTP/HTTPS访问
- 支持CDN加速
- 全球边缘节点分发
S3存储类别选择指南
S3提供多种存储类别,就像酒店的不同房型,价格和服务不同:
Standard(标准存储)
# 特点:
# • 高频访问
# • 毫秒级访问延迟
# • 99.99%可用性
# • 适合:网站资源、移动应用、游戏应用
# 定价示例(美国东部):
# 存储:$0.023/GB/月
# 请求:$0.0004/1000次GET请求
Standard-IA(标准不频繁访问)
# 特点:
# • 低频访问但需要快速访问
# • 毫秒级访问延迟
# • 99.9%可用性
# • 适合:备份、灾难恢复、长期存储
# 定价示例:
# 存储:$0.0125/GB/月
# 请求:$0.001/1000次GET请求
# 检索:$0.01/GB
Glacier(冰川存储)
# 特点:
# • 归档存储
# • 检索时间:1分钟-12小时
# • 99.999999999%持久性
# • 适合:长期归档、合规备份
# 定价示例:
# 存储:$0.004/GB/月
# 检索:$0.03/GB(标准检索)
Intelligent-Tiering(智能分层)
# 特点:
# • 自动在存储类别间移动对象
# • 基于访问模式优化成本
# • 无检索费用
# • 适合:访问模式不确定的数据
# 定价示例:
# 监控费用:$0.0025/1000个对象/月
# 自动分层,无额外费用
实战案例:WordPress静态资源迁移到S3
让我们将WordPress的静态资源迁移到S3,实现存储和访问的优化。
步骤1:创建S3桶
使用控制台创建
- 桶名称:选择全球唯一的名称,如
my-wordpress-assets-20231201
- 区域:选择离用户最近的区域
- 公共访问设置:暂时阻止所有公共访问(稍后配置)
- 版本控制:启用(便于文件管理)
- 加密:启用服务器端加密
使用命令行创建
# 创建S3桶
aws s3 mb s3://my-wordpress-assets-20231201 --region us-east-1
# 启用版本控制
aws s3api put-bucket-versioning \
--bucket my-wordpress-assets-20231201 \
--versioning-configuration Status=Enabled
# 启用服务器端加密
aws s3api put-bucket-encryption \
--bucket my-wordpress-assets-20231201 \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
}'
步骤2:配置桶权限
# 创建桶策略,允许公开读取
cat > bucket-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-wordpress-assets-20231201/*"
}
]
}
EOF
# 应用桶策略
aws s3api put-bucket-policy \
--bucket my-wordpress-assets-20231201 \
--policy file://bucket-policy.json
# 禁用阻止公共访问(仅针对GetObject)
aws s3api put-public-access-block \
--bucket my-wordpress-assets-20231201 \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=false,RestrictPublicBuckets=false"
步骤3:上传现有静态资源
# 连接到EC2实例
ssh -i my-key.pem ec2-user@your-ec2-ip
# 同步wp-content/uploads到S3
aws s3 sync /var/www/html/wp-content/uploads/ \
s3://my-wordpress-assets-20231201/wp-content/uploads/ \
--delete
# 同步主题文件
aws s3 sync /var/www/html/wp-content/themes/ \
s3://my-wordpress-assets-20231201/wp-content/themes/ \
--exclude "*.php" \
--include "*.css" \
--include "*.js" \
--include "*.png" \
--include "*.jpg" \
--include "*.gif"
# 查看上传结果
aws s3 ls s3://my-wordpress-assets-20231201/wp-content/uploads/ --recursive
步骤4:配置WordPress使用S3
方法1:使用插件(推荐初学者)
# 安装WP CLI(如果还没有)
curl -O https://raw.githubusercontent.com/wp-cli/wp-cli/v2.8.1/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
# 安装S3插件
cd /var/www/html
wp plugin install amazon-s3-and-cloudfront --activate --allow-root
在WordPress管理后台配置插件:
- 进入 “AWS” → “S3 and CloudFront”
- 输入S3桶名称:
my-wordpress-assets-20231201
- 选择区域:
us-east-1
- 启用 “Copy files to S3”
- 启用 “Serve files from S3”
方法2:修改WordPress配置(高级用户)
// 在wp-config.php中添加S3配置
define('S3_UPLOADS_BUCKET', 'my-wordpress-assets-20231201');
define('S3_UPLOADS_REGION', 'us-east-1');
define('S3_UPLOADS_BASE_URL', 'https://my-wordpress-assets-20231201.s3.amazonaws.com');
// 修改上传目录
add_filter('upload_dir', function($uploads) {
$uploads['url'] = 'https://my-wordpress-assets-20231201.s3.amazonaws.com/wp-content/uploads';
$uploads['baseurl'] = 'https://my-wordpress-assets-20231201.s3.amazonaws.com/wp-content/uploads';
return $uploads;
});
步骤5:测试S3访问
# 测试直接访问S3文件
curl -I https://my-wordpress-assets-20231201.s3.amazonaws.com/wp-content/uploads/2023/12/test-image.jpg
# 检查WordPress网站图片显示
curl -s http://your-ec2-ip | grep -o 'https://my-wordpress-assets-20231201.s3.amazonaws.com[^"]*'
S3高级功能配置
生命周期管理
自动管理文件的存储类别,优化成本:
# 创建生命周期配置
cat > lifecycle-policy.json << EOF
{
"Rules": [
{
"ID": "WordPressAssetsLifecycle",
"Status": "Enabled",
"Filter": {
"Prefix": "wp-content/uploads/"
},
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER"
},
{
"Days": 365,
"StorageClass": "DEEP_ARCHIVE"
}
]
},
{
"ID": "DeleteIncompleteMultipartUploads",
"Status": "Enabled",
"Filter": {},
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": 7
}
}
]
}
EOF
# 应用生命周期策略
aws s3api put-bucket-lifecycle-configuration \
--bucket my-wordpress-assets-20231201 \
--lifecycle-configuration file://lifecycle-policy.json
版本控制和删除保护
# 启用MFA删除保护(需要root用户)
aws s3api put-bucket-versioning \
--bucket my-wordpress-assets-20231201 \
--versioning-configuration Status=Enabled,MFADelete=Enabled \
--mfa "arn:aws:iam::123456789012:mfa/root-account-mfa-device 123456"
# 查看对象版本
aws s3api list-object-versions \
--bucket my-wordpress-assets-20231201 \
--prefix wp-content/uploads/2023/12/
# 恢复删除的对象
aws s3api delete-object \
--bucket my-wordpress-assets-20231201 \
--key wp-content/uploads/2023/12/deleted-image.jpg \
--version-id null
跨区域复制
为重要资源设置跨区域备份:
# 创建目标桶(不同区域)
aws s3 mb s3://my-wordpress-backup-20231201 --region us-west-2
# 创建复制角色
cat > replication-role-trust-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role \
--role-name S3ReplicationRole \
--assume-role-policy-document file://replication-role-trust-policy.json
# 附加复制权限
aws iam attach-role-policy \
--role-name S3ReplicationRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSS3ReplicationServiceRolePolicy
# 配置复制规则
cat > replication-config.json << EOF
{
"Role": "arn:aws:iam::123456789012:role/S3ReplicationRole",
"Rules": [
{
"ID": "ReplicateUploads",
"Status": "Enabled",
"Priority": 1,
"Filter": {
"Prefix": "wp-content/uploads/"
},
"Destination": {
"Bucket": "arn:aws:s3:::my-wordpress-backup-20231201",
"StorageClass": "STANDARD_IA"
}
}
]
}
EOF
aws s3api put-bucket-replication \
--bucket my-wordpress-assets-20231201 \
--replication-configuration file://replication-config.json
静态网站托管
S3不仅可以存储文件,还可以直接托管静态网站:
配置静态网站托管
# 启用静态网站托管
aws s3api put-bucket-website \
--bucket my-wordpress-assets-20231201 \
--website-configuration '{
"IndexDocument": {
"Suffix": "index.html"
},
"ErrorDocument": {
"Key": "error.html"
}
}'
# 创建简单的index.html
cat > index.html << EOF
<!DOCTYPE html>
<html>
<head>
<title>My WordPress Assets</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.container { max-width: 800px; margin: 0 auto; }
.asset-list { list-style: none; padding: 0; }
.asset-list li { padding: 10px; border-bottom: 1px solid #eee; }
</style>
</head>
<body>
<div class="container">
<h1>WordPress Static Assets</h1>
<p>This bucket contains static assets for our WordPress site.</p>
<ul class="asset-list">
<li><a href="wp-content/uploads/">Uploads Directory</a></li>
<li><a href="wp-content/themes/">Themes Directory</a></li>
</ul>
</div>
</body>
</html>
EOF
# 上传index.html
aws s3 cp index.html s3://my-wordpress-assets-20231201/ \
--content-type "text/html"
# 访问静态网站
echo "Website URL: http://my-wordpress-assets-20231201.s3-website-us-east-1.amazonaws.com"
自定义域名绑定
# 创建CNAME记录(在你的DNS提供商)
# assets.yourdomain.com -> my-wordpress-assets-20231201.s3-website-us-east-1.amazonaws.com
# 或使用Route 53
aws route53 change-resource-record-sets \
--hosted-zone-id Z123456789 \
--change-batch '{
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "assets.yourdomain.com",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "my-wordpress-assets-20231201.s3-website-us-east-1.amazonaws.com"
}
]
}
}
]
}'
文件上传和管理
批量上传工具
# 使用AWS CLI同步
aws s3 sync /local/path/ s3://my-wordpress-assets-20231201/path/ \
--exclude "*.tmp" \
--include "*.jpg" \
--include "*.png" \
--include "*.css" \
--include "*.js" \
--delete \
--dryrun # 先预览,确认无误后去掉此参数
# 设置文件元数据
aws s3 cp image.jpg s3://my-wordpress-assets-20231201/wp-content/uploads/2023/12/ \
--metadata "title=My Image,description=A beautiful image" \
--content-type "image/jpeg" \
--cache-control "max-age=31536000"
# 批量设置缓存策略
aws s3 cp s3://my-wordpress-assets-20231201/wp-content/uploads/ \
s3://my-wordpress-assets-20231201/wp-content/uploads/ \
--recursive \
--metadata-directive REPLACE \
--cache-control "max-age=31536000" \
--content-type "image/jpeg" \
--exclude "*" \
--include "*.jpg"
预签名URL
为私有文件生成临时访问链接:
# 生成1小时有效的下载链接
aws s3 presign s3://my-wordpress-assets-20231201/private/document.pdf \
--expires-in 3600
# 生成上传链接
aws s3 presign s3://my-wordpress-assets-20231201/uploads/new-file.jpg \
--expires-in 3600 \
--http-method PUT
多部分上传
对于大文件,使用多部分上传提高效率:
# 启动多部分上传
UPLOAD_ID=$(aws s3api create-multipart-upload \
--bucket my-wordpress-assets-20231201 \
--key large-video.mp4 \
--query 'UploadId' \
--output text)
# 分块上传(示例:分成3个部分)
aws s3api upload-part \
--bucket my-wordpress-assets-20231201 \
--key large-video.mp4 \
--part-number 1 \
--upload-id $UPLOAD_ID \
--body part1.mp4
aws s3api upload-part \
--bucket my-wordpress-assets-20231201 \
--key large-video.mp4 \
--part-number 2 \
--upload-id $UPLOAD_ID \
--body part2.mp4
aws s3api upload-part \
--bucket my-wordpress-assets-20231201 \
--key large-video.mp4 \
--part-number 3 \
--upload-id $UPLOAD_ID \
--body part3.mp4
# 完成上传
aws s3api complete-multipart-upload \
--bucket my-wordpress-assets-20231201 \
--key large-video.mp4 \
--upload-id $UPLOAD_ID \
--multipart-upload file://parts.json
性能优化
请求优化
# 使用Transfer Acceleration
aws s3api put-bucket-accelerate-configuration \
--bucket my-wordpress-assets-20231201 \
--accelerate-configuration Status=Enabled
# 使用加速端点上传
aws s3 cp large-file.zip \
s3://my-wordpress-assets-20231201/ \
--endpoint-url https://s3-accelerate.amazonaws.com
缓存策略
# 为不同文件类型设置不同的缓存策略
# 图片文件 - 长期缓存
aws s3 cp s3://my-wordpress-assets-20231201/wp-content/uploads/ \
s3://my-wordpress-assets-20231201/wp-content/uploads/ \
--recursive \
--metadata-directive REPLACE \
--cache-control "max-age=31536000, public" \
--exclude "*" \
--include "*.jpg" \
--include "*.png" \
--include "*.gif"
# CSS/JS文件 - 中期缓存
aws s3 cp s3://my-wordpress-assets-20231201/wp-content/themes/ \
s3://my-wordpress-assets-20231201/wp-content/themes/ \
--recursive \
--metadata-directive REPLACE \
--cache-control "max-age=86400, public" \
--exclude "*" \
--include "*.css" \
## 监控和故障排除
### CloudWatch监控
```bash
# 查看存储使用量
aws cloudwatch get-metric-statistics \
--namespace AWS/S3 \
--metric-name BucketSizeBytes \
--dimensions Name=BucketName,Value=my-wordpress-assets-20231201 Name=StorageType,Value=StandardStorage \
--start-time 2023-12-01T00:00:00Z \
--end-time 2023-12-01T23:59:59Z \
--period 86400 \
--statistics Maximum
# 查看请求数量
aws cloudwatch get-metric-statistics \
--namespace AWS/S3 \
--metric-name AllRequests \
--dimensions Name=BucketName,Value=my-wordpress-assets-20231201 \
--start-time 2023-12-01T00:00:00Z \
--end-time 2023-12-01T23:59:59Z \
--period 3600 \
--statistics Sum
# 设置告警
aws cloudwatch put-metric-alarm \
--alarm-name "S3-High-Request-Count" \
--alarm-description "Alert when S3 requests are high" \
--metric-name AllRequests \
--namespace AWS/S3 \
--statistic Sum \
--period 3600 \
--threshold 10000 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--dimensions Name=BucketName,Value=my-wordpress-assets-20231201
常见问题解决
问题1:403 Forbidden错误
# 检查桶策略
aws s3api get-bucket-policy --bucket my-wordpress-assets-20231201
# 检查公共访问阻止设置
aws s3api get-public-access-block --bucket my-wordpress-assets-20231201
# 检查对象ACL
aws s3api get-object-acl \
--bucket my-wordpress-assets-20231201 \
--key wp-content/uploads/2023/12/image.jpg
问题2:上传失败
# 检查IAM权限
aws iam get-user-policy --user-name your-username --policy-name S3Access
# 检查文件大小限制
ls -lh large-file.zip
# 使用多部分上传
aws configure set default.s3.multipart_threshold 64MB
aws configure set default.s3.multipart_chunksize 16MB
问题3:访问速度慢
# 检查区域选择
aws s3api get-bucket-location --bucket my-wordpress-assets-20231201
# 启用Transfer Acceleration
aws s3api put-bucket-accelerate-configuration \
--bucket my-wordpress-assets-20231201 \
--accelerate-configuration Status=Enabled
# 测试加速效果
aws s3 cp test-file.jpg s3://my-wordpress-assets-20231201/ \
--endpoint-url https://s3-accelerate.amazonaws.com
自动化管理
Lambda函数自动处理
创建Lambda函数自动优化上传的图片:
import json
import boto3
from PIL import Image
import io
def lambda_handler(event, context):
s3 = boto3.client('s3')
# 获取触发事件的桶和对象信息
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
# 只处理图片文件
if not key.lower().endswith(('.jpg', '.jpeg', '.png')):
return {'statusCode': 200, 'body': 'Not an image file'}
try:
# 下载原始图片
response = s3.get_object(Bucket=bucket, Key=key)
image_data = response['Body'].read()
# 使用PIL处理图片
image = Image.open(io.BytesIO(image_data))
# 创建缩略图
thumbnail = image.copy()
thumbnail.thumbnail((300, 300), Image.Resampling.LANCZOS)
# 保存缩略图
thumb_buffer = io.BytesIO()
thumbnail.save(thumb_buffer, format=image.format, optimize=True, quality=85)
thumb_buffer.seek(0)
# 上传缩略图到S3
thumb_key = key.replace('/uploads/', '/uploads/thumbs/')
s3.put_object(
Bucket=bucket,
Key=thumb_key,
Body=thumb_buffer.getvalue(),
ContentType=response['ContentType'],
CacheControl='max-age=31536000'
)
return {
'statusCode': 200,
'body': json.dumps(f'Thumbnail created: {thumb_key}')
}
except Exception as e:
print(f'Error processing {key}: {str(e)}')
return {
'statusCode': 500,
'body': json.dumps(f'Error: {str(e)}')
}
事件通知配置
# 配置S3事件通知
cat > notification-config.json << EOF
{
"LambdaConfigurations": [
{
"Id": "ImageProcessing",
"LambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:ProcessS3Images",
"Events": ["s3:ObjectCreated:*"],
"Filter": {
"Key": {
"FilterRules": [
{
"Name": "prefix",
"Value": "wp-content/uploads/"
},
{
"Name": "suffix",
"Value": ".jpg"
}
]
}
}
}
]
}
EOF
aws s3api put-bucket-notification-configuration \
--bucket my-wordpress-assets-20231201 \
--notification-configuration file://notification-config.json
备份和灾难恢复
跨账户备份
# 创建跨账户复制策略
cat > cross-account-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountReplication",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::BACKUP-ACCOUNT-ID:root"
},
"Action": [
"s3:GetBucketVersioning",
"s3:PutBucketVersioning",
"s3:ReplicateObject",
"s3:ReplicateDelete"
],
"Resource": [
"arn:aws:s3:::my-wordpress-backup-account",
"arn:aws:s3:::my-wordpress-backup-account/*"
]
}
]
}
EOF
数据恢复流程
# 恢复删除的对象
aws s3api list-object-versions \
--bucket my-wordpress-assets-20231201 \
--prefix wp-content/uploads/2023/12/deleted-image.jpg
# 恢复特定版本
aws s3api copy-object \
--copy-source "my-wordpress-assets-20231201/wp-content/uploads/2023/12/deleted-image.jpg?versionId=VERSION_ID" \
--bucket my-wordpress-assets-20231201 \
--key wp-content/uploads/2023/12/deleted-image.jpg
# 批量恢复
aws s3 sync s3://my-wordpress-backup-20231201/ s3://my-wordpress-assets-20231201/ \
--delete \
--dryrun # 先预览
迁移验证清单
功能验证
- WordPress网站图片正常显示
- 媒体库文件可以正常上传
- 主题CSS和JS文件正常加载
- 文件下载功能正常
- 搜索引擎可以正常索引图片
性能验证
# 测试文件访问速度
time curl -o /dev/null -s https://my-wordpress-assets-20231201.s3.amazonaws.com/wp-content/uploads/2023/12/large-image.jpg
# 测试网站加载速度
curl -w "@curl-format.txt" -o /dev/null -s http://your-ec2-ip
# 检查缓存头
curl -I https://my-wordpress-assets-20231201.s3.amazonaws.com/wp-content/uploads/2023/12/image.jpg
成本验证
# 查看S3使用量
aws s3 ls s3://my-wordpress-assets-20231201 --recursive --summarize
# 检查存储类别分布
aws s3api list-objects-v2 \
--bucket my-wordpress-assets-20231201 \
--query 'Contents[].{Key:Key,StorageClass:StorageClass,Size:Size}'
WordPress插件推荐
WP Offload Media
- 自动上传媒体文件到S3
- 支持CDN集成
- 提供图片优化功能
S3 Uploads
- 轻量级S3集成
- 开源免费
- 适合开发者使用
WP-Stateless
- Google Cloud Storage和S3双支持
- 图片处理功能
- 性能优化
最佳实践总结
命名规范
# 桶命名
company-project-environment-date
# 例如:mycompany-wordpress-prod-20231201
# 对象键命名
service/type/date/filename
# 例如:wp-content/uploads/2023/12/image-001.jpg
权限管理
- 使用最小权限原则
- 定期审查桶策略
- 启用访问日志记录
- 使用IAM角色而非用户密钥
成本控制
- 合理选择存储类别
- 设置生命周期策略
- 监控请求数量
- 使用CloudFront减少直接请求
安全配置
- 启用版本控制
- 配置跨区域复制
- 使用服务器端加密
- 限制公共访问权限
下一步学习方向
掌握了S3基础后,你可以继续探索:
- CloudFront CDN:为S3内容提供全球加速(下一篇文章重点)
- Lambda@Edge:在边缘节点处理请求
- S3 Select:直接查询S3中的数据
- AWS DataSync:大规模数据迁移
- S3 Batch Operations:批量处理S3对象
结语
通过将静态资源迁移到S3,我们不仅解决了存储空间的问题,还获得了更好的性能、可靠性和成本效益。S3就像一个无限容量的"云端仓库",不仅安全可靠,还能根据我们的需求提供不同级别的服务。
从本地存储到云端存储,这不仅是技术架构的升级,更是存储思维的转变。我们学会了:
- 根据访问频率选择合适的存储类别
- 使用生命周期策略自动优化成本
- 通过版本控制和跨区域复制保障数据安全
- 利用事件通知实现自动化处理
现在我们的架构已经包含了:
- 计算层:EC2(动态内容)
- 数据层:RDS(数据库)
- 存储层:S3(静态资源)
在下一篇文章中,我们将学习CloudFront CDN服务,为我们的S3内容和EC2应用提供全球加速,让世界各地的用户都能快速访问我们的网站。
静态资源有了新家,网站性能更上一层楼!S3让存储变得如此简单而强大!
压缩优化
# 启用Gzip压缩
aws s3 cp style.css s3://my-wordpress-assets-20231201/wp-content/themes/mytheme/ \
--content-encoding gzip \
--content-type "text/css"
# 批量压缩CSS和JS文件
find /var/www/html/wp-content/themes -name "*.css" -o -name "*.js" | while read file; do
gzip -c "$file" > "${file}.gz"
aws s3 cp "${file}.gz" "s3://my-wordpress-assets-20231201${file#/var/www/html}" \
--content-encoding gzip \
--content-type "$(file -b --mime-type "$file")"
rm "${file}.gz"
done
安全配置
访问控制
# 创建更精细的桶策略
cat > secure-bucket-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-wordpress-assets-20231201/wp-content/uploads/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://yourdomain.com/*",
"https://yourdomain.com/*"
]
}
}
},
{
"Sid": "DenyDirectAccess",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-wordpress-assets-20231201/private/*"
}
]
}
EOF
aws s3api put-bucket-policy \
--bucket my-wordpress-assets-20231201 \
--policy file://secure-bucket-policy.json
访问日志
# 创建日志桶
aws s3 mb s3://my-wordpress-access-logs-20231201
# 启用访问日志
aws s3api put-bucket-logging \
--bucket my-wordpress-assets-20231201 \
--bucket-logging-status '{
"LoggingEnabled": {
"TargetBucket": "my-wordpress-access-logs-20231201",
"TargetPrefix": "access-logs/"
}
}'
数据加密
# 启用默认加密
aws s3api put-bucket-encryption \
--bucket my-wordpress-assets-20231201 \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
},
"BucketKeyEnabled": true
}
]
}'
# 上传加密文件
aws s3 cp sensitive-document.pdf \
s3://my-wordpress-assets-20231201/private/ \
--server-side-encryption aws:kms \
--ssekms-key-id arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
成本优化策略
存储类别优化
# 分析存储使用情况
aws s3api get-bucket-analytics-configuration \
--bucket my-wordpress-assets-20231201 \
--id EntireBucket
# 启用智能分层
aws s3 cp s3://my-wordpress-assets-20231201/ \
s3://my-wordpress-assets-20231201/ \
--recursive \
--storage-class INTELLIGENT_TIERING
成本监控
# 设置S3成本预算
aws budgets create-budget \
--account-id 123456789012 \
--budget '{
"BudgetName": "S3-Monthly-Budget",
"BudgetLimit": {
"Amount": "20",
"Unit": "USD"
},
"TimeUnit": "MONTHLY",
"BudgetType": "COST",
"CostFilters": {
"Service": ["Amazon Simple Storage Service"]
}
}'
# 查看存储使用量
aws cloudwatch get-metric-statistics \
--namespace AWS/S3 \
--metric-name BucketSizeBytes \
--dimensions Name=BucketName,Value=my-wordpress-assets-20231201 Name=StorageType,Value=StandardStorage \
--start-time 2023-11-01T00:00:00Z \
--end-time 2023-12-01T00:00:00Z \
--period 86400 \
--statistics Average
请求成本优化
# 使用CloudFront减少S3请求
# (这将在下一篇文章详细介绍)
# 批量删除过期文件
aws s3api list-objects-v2 \
--bucket my-wordpress-assets-20231201 \
--query 'Contents[?LastModified<`2023-01-01`].Key' \
--output text | \
xargs -I {} aws s3 rm s3://my-wordpress-assets-20231201/{}