AWS 是领先的云平台,拥有 200+ 服务。对于大多数应用,掌握这六个核心服务即可:EC2(虚拟机)、S3(对象存储)、Lambda(无服务器计算)、RDS(托管数据库)、CloudFront(CDN)和 IAM(身份/访问控制)。使用 AWS 免费套餐学习,立即设置账单警报,使用 IAM 角色而非长期访问密钥。
Amazon Web Services(AWS)是世界上最全面的云平台,拥有 200 多项全功能服务,涵盖计算、存储、网络、数据库、AI/ML、安全等领域。AWS 于 2006 年仅以 S3 和 EC2 起步,现在为从初创企业到财富 500 强的数百万应用程序提供支持。无论你是在运行个人项目还是设计全球分布式系统,了解基本的 AWS 服务是现代开发者的关键技能。本指南涵盖你日常使用的最重要服务,附带真实的 CLI 命令、IAM 策略示例、架构模式和成本优化策略。
- IAM 角色始终比带有访问密钥的 IAM 用户更安全——对 EC2 实例、Lambda 函数和 CI/CD 流水线使用角色。
- S3 + CloudFront 是托管静态网站和全球提供大文件的最便宜、最可扩展的方式。
- Lambda 冷启动对 Node.js/Python 影响比 Java/C# 小——对延迟敏感的工作负载使用预置并发保持函数预热。
- RDS Multi-AZ 提供自动故障转移;只读副本提供读取可扩展性——它们是独立功能,如有需要可同时使用。
- 始终为每个 AWS 资源打至少以下标签:Project(项目)、Environment(环境)、Owner(负责人)——这将大大简化成本分配和清理工作。
- 使用 AWS Cost Explorer 并在开始之前设置账单警报——意外账单是 AWS 初学者最常见的错误。
AWS 核心概念:区域、可用区和 IAM
在深入了解具体服务之前,你需要了解 AWS 如何组织其全球基础设施并控制访问。
区域和可用区
AWS 在 33+ 个地理区域运营,每个区域包含 3+ 个可用区(AZ)。区域是独立的地理区域(如 us-east-1、eu-west-1、ap-southeast-1)。AZ 是区域内物理分离的数据中心,具有独立的电源、冷却和网络。跨多个 AZ 部署可防止数据中心故障。某些服务(IAM、CloudFront、Route 53)是全球性的;大多数(EC2、RDS、Lambda)是区域性的。
# List all regions
aws ec2 describe-regions --output table
# Set a default region in environment
export AWS_DEFAULT_REGION=us-east-1
# Set region in AWS CLI profile
aws configure set region us-east-1
# List AZs in current region
aws ec2 describe-availability-zones \
--query "AvailabilityZones[].ZoneName" \
--output textIAM:身份和访问管理
IAM 是 AWS 安全的基础。它控制谁可以访问 AWS 服务以及可以执行哪些操作。核心组件包括:用户(具有长期凭证的人员或应用程序)、组(用户集合)、角色(由 AWS 服务或外部身份承担——无静态凭证)和策略(定义权限的 JSON 文档)。黄金法则:始终使用角色而非访问密钥,并应用最小权限原则。
# Example IAM policy — least privilege for S3 read on specific bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadSpecificBucket",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-app-bucket",
"arn:aws:s3:::my-app-bucket/*"
]
}
]
}
# Create an IAM role for EC2 (trust policy)
aws iam create-role \
--role-name MyEC2Role \
--assume-role-policy-document file://ec2-trust-policy.json
# Attach a managed policy
aws iam attach-role-policy \
--role-name MyEC2Role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# Create instance profile and add role
aws iam create-instance-profile --instance-profile-name MyEC2Profile
aws iam add-role-to-instance-profile \
--instance-profile-name MyEC2Profile \
--role-name MyEC2Role了解 AWS 定价
AWS 使用按需付费模式。主要定价概念:按需(按秒/小时付费,无承诺)、预留实例(1-3 年承诺,最高节省 72%)、Spot 实例(未使用容量,最高节省 90% 但可能被中断)、节省计划(跨实例系列的灵活承诺)和免费套餐(新账户前 12 个月特定服务免费)。在部署生产工作负载之前,始终使用 AWS 定价计算器。
EC2:弹性计算云
EC2 在云中提供可调整大小的虚拟机(称为实例)。它是许多 AWS 架构的基础。你选择操作系统、实例类型、存储和网络配置。
EC2 实例类型系列
AWS 提供数百种按系列组织的实例类型。命名格式为:[系列][代数].[大小](如 t3.micro、m5.xlarge、c6i.2xlarge)。
| Family | Purpose | Examples | Use Cases |
|---|---|---|---|
t3/t4g | Burstable General Purpose | t3.micro, t3.small, t4g.medium | Dev/test, low-traffic web apps, small DBs |
m5/m6i | General Purpose | m5.large, m6i.xlarge, m6a.2xlarge | Web apps, app servers, small-medium DBs |
c5/c6i | Compute Optimized | c5.large, c6i.2xlarge, c6g.4xlarge | Batch processing, ML inference, gaming |
r5/r6i | Memory Optimized | r5.large, r6i.2xlarge, x2idn.32xlarge | In-memory DBs, Redis, Elasticsearch, SAP |
i3/i4i | Storage Optimized | i3.large, i4i.xlarge, d3en.2xlarge | NoSQL DBs, data warehousing, Kafka |
p3/p4d | GPU Instances | p3.2xlarge, p4d.24xlarge, g5.xlarge | ML training, GPU rendering, HPC |
安全组
安全组作为 EC2 实例的虚拟防火墙,在实例级别控制入站和出站流量。与 NACL 不同,安全组是有状态的:如果允许入站流量,响应将自动被允许。
# Create a security group
aws ec2 create-security-group \
--group-name my-web-sg \
--description "Web server security group" \
--vpc-id vpc-0123456789abcdef0
# Allow HTTP from anywhere
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp --port 80 --cidr 0.0.0.0/0
# Allow HTTPS from anywhere
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp --port 443 --cidr 0.0.0.0/0
# Allow SSH from specific IP only
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp --port 22 --cidr 203.0.113.0/32
# Allow traffic from another security group (e.g., ALB → EC2)
aws ec2 authorize-security-group-ingress \
--group-id sg-ec2 \
--protocol tcp --port 8080 \
--source-group sg-alb用户数据脚本
用户数据脚本在实例启动时运行,非常适合引导操作:安装软件、拉取配置或将实例注册到服务。
#!/bin/bash
# EC2 User Data — runs as root on first boot
set -euo pipefail
# Update packages
yum update -y
# Install Node.js 20 via NVM
export HOME=/root
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
source ~/.nvm/nvm.sh
nvm install 20
nvm use 20
# Install PM2 globally
npm install -g pm2
# Clone application from S3
aws s3 cp s3://my-app-bucket/app.tar.gz /tmp/app.tar.gz
mkdir -p /opt/app
tar -xzf /tmp/app.tar.gz -C /opt/app
cd /opt/app && npm install --production
# Start the application
pm2 start server.js --name my-app
pm2 startup
pm2 save
# Signal CloudFormation that instance is ready
# (if using cfn-init)
# /opt/aws/bin/cfn-signal -e $? ...# Launch an EC2 instance with user data
aws ec2 run-instances \
--image-id ami-0abcdef1234567890 \
--instance-type t3.small \
--key-name my-key-pair \
--security-group-ids sg-0123456789abcdef0 \
--subnet-id subnet-0123456789abcdef0 \
--iam-instance-profile Name=MyEC2Profile \
--user-data file://user-data.sh \
--tag-specifications \
"ResourceType=instance,Tags=[{Key=Name,Value=my-server},{Key=Environment,Value=production}]" \
--count 1S3:简单存储服务
S3 是 AWS 的对象存储服务,将文件(对象)存储在容器(存储桶)中。S3 提供 11 个 9(99.999999999%)的持久性、生命周期管理、版本控制、服务器端加密和静态网站托管。
S3 存储类
S3 提供多种针对不同访问模式和成本要求优化的存储类。
| Storage Class | Retrieval | Min Duration | Cost | Use Case |
|---|---|---|---|---|
| S3 Standard | Instant | None | $$ | Frequently accessed data |
| S3 Intelligent-Tiering | Instant | None | $-$$ | Unknown/changing patterns |
| S3 Standard-IA | Instant | 30 days | $ | Infrequent access, rapid when needed |
| S3 One Zone-IA | Instant | 30 days | $ | Non-critical, reproductible data |
| S3 Glacier Instant | Instant | 90 days | ¢ | Archive with instant retrieval |
| S3 Glacier Flexible | Minutes-hours | 90 days | ¢ | Long-term archive, rare access |
| S3 Glacier Deep Archive | 12 hours | 180 days | ¢¢ | Regulatory/compliance archive |
# Create a bucket
aws s3api create-bucket \
--bucket my-app-bucket-2026 \
--region us-east-1
# For regions other than us-east-1, add LocationConstraint
aws s3api create-bucket \
--bucket my-app-bucket-2026 \
--region eu-west-1 \
--create-bucket-configuration LocationConstraint=eu-west-1
# Enable versioning
aws s3api put-bucket-versioning \
--bucket my-app-bucket-2026 \
--versioning-configuration Status=Enabled
# Enable server-side encryption (SSE-S3)
aws s3api put-bucket-encryption \
--bucket my-app-bucket-2026 \
--server-side-encryption-configuration \
"{\"Rules\":[{\"ApplyServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"AES256\"}}]}"
# Block all public access (recommended default)
aws s3api put-public-access-block \
--bucket my-app-bucket-2026 \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
# Upload a file
aws s3 cp ./index.html s3://my-app-bucket-2026/
# Sync a local directory to S3 (like rsync)
aws s3 sync ./dist s3://my-app-bucket-2026/ --delete
# Set cache headers for static assets
aws s3 sync ./dist s3://my-app-bucket-2026/ \
--cache-control "max-age=31536000,public" \
--exclude "*.html" \
--delete
# Upload HTML files with no-cache
aws s3 sync ./dist s3://my-app-bucket-2026/ \
--include "*.html" \
--cache-control "no-cache,no-store,must-revalidate"静态网站托管
S3 可以直接托管静态网站,无需任何服务器。与 CloudFront 结合,这是全球提供静态内容的最便宜方式。
# Enable static website hosting
aws s3api put-bucket-website \
--bucket my-app-bucket-2026 \
--website-configuration \
"{\"IndexDocument\":{\"Suffix\":\"index.html\"},\"ErrorDocument\":{\"Key\":\"404.html\"}}""
# Set bucket policy for public read (required for static hosting)
cat > bucket-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-app-bucket-2026/*"
}]
}
EOF
aws s3api put-bucket-policy \
--bucket my-app-bucket-2026 \
--policy file://bucket-policy.json
# Your website is now at:
# http://my-app-bucket-2026.s3-website-us-east-1.amazonaws.com
# Point CloudFront at this origin for HTTPS + CDN预签名 URL
预签名 URL 允许对私有 S3 对象进行临时、经过身份验证的访问,而无需暴露你的凭证。它们对于用户文件上传和安全下载至关重要。
# CLI: Generate presigned GET URL (valid 1 hour)
aws s3 presign s3://my-app-bucket-2026/private-file.pdf \
--expires-in 3600
# Node.js SDK v3: Presigned PUT (for user uploads)
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const s3 = new S3Client({ region: "us-east-1" });
async function getUploadUrl(key: string, contentType: string) {
const command = new PutObjectCommand({
Bucket: "my-app-bucket-2026",
Key: key,
ContentType: contentType,
});
// URL expires in 15 minutes
const url = await getSignedUrl(s3, command, { expiresIn: 900 });
return url;
}
// Client uploads directly to S3 (no server bandwidth used)
const url = await getUploadUrl("uploads/avatar.jpg", "image/jpeg");
await fetch(url, {
method: "PUT",
body: file,
headers: { "Content-Type": "image/jpeg" },
});Lambda:无服务器函数
Lambda 无需预置或管理服务器即可运行你的代码。你只需为消耗的计算时间付费。Lambda 支持 Node.js、Python、Go、Java、Ruby、.NET 和自定义运行时。
Lambda 触发器
Lambda 函数可以由数十种 AWS 服务和事件触发。
| Trigger Source | Invocation Type | Common Use Case |
|---|---|---|
| API Gateway / Function URL | Synchronous | REST APIs, webhooks |
| S3 (ObjectCreated, ObjectRemoved) | Asynchronous | Image processing, file transformations |
| DynamoDB Streams | Stream | Change data capture, event sourcing |
| SQS | Poll-based | Message processing, job queues |
| SNS | Asynchronous | Fan-out notifications |
| EventBridge (CloudWatch Events) | Asynchronous | Scheduled tasks, event routing |
| Kinesis Data Streams | Stream | Real-time analytics, log processing |
| Cognito | Synchronous | Custom auth flows, user pool triggers |
| CloudFront (Lambda@Edge) | Synchronous | Request/response manipulation at edge |
// Lambda handler best practices — Node.js 20
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall } from "@aws-sdk/util-dynamodb";
// Initialize clients OUTSIDE the handler (reused across warm invocations)
const dynamo = new DynamoDBClient({ region: process.env.AWS_REGION });
// Type the event — import from @types/aws-lambda
export const handler = async (event: AWSLambda.APIGatewayProxyEventV2) => {
// Always log structured JSON for CloudWatch Insights queries
console.log(JSON.stringify({ event: "request", path: event.rawPath }));
try {
const body = JSON.parse(event.body || "{}") as { name: string };
await dynamo.send(new PutItemCommand({
TableName: process.env.TABLE_NAME!,
Item: marshall({
pk: "USER#" + Date.now(),
name: body.name,
createdAt: new Date().toISOString(),
}),
}));
return {
statusCode: 201,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ success: true }),
};
} catch (err) {
console.error(JSON.stringify({ error: String(err) }));
return { statusCode: 500, body: JSON.stringify({ error: "Internal error" }) };
}
};
# Deploy Lambda via AWS CLI
# 1. Create deployment package
npm run build && zip -r function.zip dist/ node_modules/
# 2. Create the function
aws lambda create-function \
--function-name my-api-handler \
--runtime nodejs20.x \
--role arn:aws:iam::123456789012:role/LambdaExecutionRole \
--handler dist/index.handler \
--zip-file fileb://function.zip \
--timeout 30 \
--memory-size 256 \
--environment "Variables={TABLE_NAME=my-table,LOG_LEVEL=info}"
# 3. Update function code (redeploy)
aws lambda update-function-code \
--function-name my-api-handler \
--zip-file fileb://function.zip
# 4. Enable Provisioned Concurrency (eliminate cold starts)
aws lambda put-provisioned-concurrency-config \
--function-name my-api-handler \
--qualifier prod \
--provisioned-concurrent-executions 5理解冷启动
当 Lambda 必须为函数初始化新的执行环境时,会发生冷启动。这会增加延迟:Node.js/Python 100ms-1s,Java/C# 1-5s。减少冷启动的策略包括:保持函数体积小、为延迟敏感的函数使用预置并发、在处理程序外初始化 SDK 客户端,以及使用更轻量的运行时(Node.js 而非 Java)。
Lambda 层
层允许跨多个 Lambda 函数共享代码和依赖项。层是包含库、自定义运行时或数据的 ZIP 存档。函数最多可使用 5 个层,层可以版本化。
# Create a Lambda layer (e.g., shared utilities + node_modules)
# Layer structure: nodejs/node_modules/...
mkdir -p layer/nodejs
cp -r node_modules layer/nodejs/
cd layer && zip -r ../shared-deps-layer.zip nodejs/
# Publish the layer
aws lambda publish-layer-version \
--layer-name shared-dependencies \
--description "Shared node_modules for production" \
--zip-file fileb://shared-deps-layer.zip \
--compatible-runtimes nodejs18.x nodejs20.x
# Attach layer to a function
aws lambda update-function-configuration \
--function-name my-api-handler \
--layers arn:aws:lambda:us-east-1:123456789012:layer:shared-dependencies:3API Gateway:REST 和 HTTP API
API Gateway 是 Lambda 函数和后端服务的入口。它处理身份验证、限流、缓存、CORS 和请求/响应转换。
REST API vs HTTP API
API Gateway 提供两种主要 API 类型。REST API 功能更丰富(请求验证、使用计划、缓存、WAF 集成)但成本更高。HTTP API 更简单、更快(更低延迟),成本降低 70%。将 HTTP API 用于 Lambda 集成,将 REST API 用于需要高级功能的场景。
| Feature | REST API | HTTP API |
|---|---|---|
| Pricing (per million) | $3.50 | $1.00 |
| Latency | Higher | Lower (~60% faster) |
| Request Validation | Yes | No |
| WAF Integration | Yes | No |
| Usage Plans / API Keys | Yes | No |
| Response Caching | Yes | No |
| Lambda Proxy Integration | Yes | Yes (optimized) |
| JWT Authorizers | Via Lambda | Native |
| CORS | Manual | Auto-configure |
| Private API (VPC) | Yes | No |
# Create an HTTP API (recommended for Lambda)
aws apigatewayv2 create-api \
--name my-http-api \
--protocol-type HTTP \
--cors-configuration \
"AllowOrigins=[https://myapp.com],AllowMethods=[GET,POST,PUT,DELETE],AllowHeaders=[Content-Type,Authorization]"
# Create Lambda integration
aws apigatewayv2 create-integration \
--api-id abc123 \
--integration-type AWS_PROXY \
--integration-uri arn:aws:lambda:us-east-1:123456789012:function:my-api-handler \
--payload-format-version 2.0
# Create a route
aws apigatewayv2 create-route \
--api-id abc123 \
--route-key "POST /users" \
--target integrations/xyz789
# Add a JWT authorizer
aws apigatewayv2 create-authorizer \
--api-id abc123 \
--name CognitoJWT \
--authorizer-type JWT \
--identity-source "$request.header.Authorization" \
--jwt-configuration \
"Issuer=https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123,Audience=[my-app-client-id]"RDS:关系数据库服务
RDS 提供托管关系数据库:MySQL、PostgreSQL、MariaDB、Oracle、SQL Server 和 Aurora。AWS 处理备份、修补、Multi-AZ 故障转移和只读副本。
Multi-AZ 部署
Multi-AZ 在不同 AZ 中创建同步备用副本。在主实例故障的情况下,RDS 自动故障转移到备用实例(通常 1-2 分钟)。Multi-AZ 用于高可用性,而非读取扩展。备用实例不可读——为此使用只读副本。
# Create an RDS PostgreSQL instance with Multi-AZ
aws rds create-db-instance \
--db-instance-identifier my-postgres-prod \
--db-instance-class db.t3.medium \
--engine postgres \
--engine-version 15.4 \
--master-username admin \
--master-user-password "$(openssl rand -base64 32)" \
--allocated-storage 100 \
--storage-type gp3 \
--multi-az \
--backup-retention-period 7 \
--deletion-protection \
--enable-performance-insights \
--db-subnet-group-name my-db-subnet-group \
--vpc-security-group-ids sg-0db123456789
# Create a Read Replica in same region
aws rds create-db-instance-read-replica \
--db-instance-identifier my-postgres-replica \
--source-db-instance-identifier my-postgres-prod \
--db-instance-class db.t3.medium
# Promote replica to standalone (e.g., for region failover)
aws rds promote-read-replica \
--db-instance-identifier my-postgres-replica
# Enable IAM database authentication
aws rds modify-db-instance \
--db-instance-identifier my-postgres-prod \
--enable-iam-database-authentication \
--apply-immediately快照和备份
RDS 支持自动备份(1-35 天保留期)和持续到删除的手动快照。你可以还原到保留期内的任意时间点,或从快照创建新实例。
# Create a manual snapshot
aws rds create-db-snapshot \
--db-instance-identifier my-postgres-prod \
--db-snapshot-identifier my-postgres-backup-2026-02-27
# Restore from snapshot (creates a new instance)
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier my-postgres-restored \
--db-snapshot-identifier my-postgres-backup-2026-02-27 \
--db-instance-class db.t3.medium
# Restore to a specific point in time
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier my-postgres-prod \
--target-db-instance-identifier my-postgres-pitr \
--restore-time 2026-02-26T12:00:00ZDynamoDB:大规模 NoSQL
DynamoDB 是完全托管的 NoSQL 数据库,在任何规模下都具有个位数毫秒延迟。它是无模式、无服务器的,自动处理分区。适合读/写模式可预测的高流量应用程序。
索引:GSI 和 LSI
DynamoDB 有两种辅助索引类型。本地辅助索引(LSI)共享分区键但具有不同的排序键——必须在创建表时创建。全局辅助索引(GSI)可以有完全不同的分区键和排序键——可以随时创建,有自己的读/写容量。
# Create a DynamoDB table with GSI
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions \
AttributeName=PK,AttributeType=S \
AttributeName=SK,AttributeType=S \
AttributeName=GSI1PK,AttributeType=S \
AttributeName=GSI1SK,AttributeType=S \
--key-schema \
AttributeName=PK,KeyType=HASH \
AttributeName=SK,KeyType=RANGE \
--global-secondary-indexes \
"[{\"IndexName\":\"GSI1\",\"KeySchema\":[{\"AttributeName\":\"GSI1PK\",\"KeyType\":\"HASH\"},{\"AttributeName\":\"GSI1SK\",\"KeyType\":\"RANGE\"}],\"Projection\":{\"ProjectionType\":\"ALL\"}}]" \
--billing-mode PAY_PER_REQUEST
# Single-table design: PK/SK patterns
# User: PK=USER#userId SK=PROFILE
# Order: PK=USER#userId SK=ORDER#orderId
# GSI1 query: PK=ORDER#status SK=createdAt (all orders by status)
# Query orders for a user
aws dynamodb query \
--table-name Orders \
--key-condition-expression "PK = :pk AND begins_with(SK, :skPrefix)" \
--expression-attribute-values \
"{\":pk\":{\"S\":\"USER#user123\"},\":skPrefix\":{\"S\":\"ORDER#\"}}"
# Query via GSI (all PENDING orders)
aws dynamodb query \
--table-name Orders \
--index-name GSI1 \
--key-condition-expression "GSI1PK = :status" \
--expression-attribute-values "{\":status\":{\"S\":\"ORDER#PENDING\"}}"DynamoDB 流
流捕获对表中项目所做的每次更改(INSERT、MODIFY、REMOVE)的按时间排序的序列。每条记录可用 24 小时。流可以触发 Lambda 函数用于事件驱动架构。
CloudFront:全球内容分发网络
CloudFront 是 AWS 的 CDN,在全球拥有 450+ 边缘位置。它将内容缓存在靠近用户的位置,减少延迟和源服务器负载。CloudFront 支持 S3、EC2、ALB、API Gateway 和自定义源。
缓存行为
行为定义 CloudFront 如何处理不同 URL 模式的请求。你可以为每个行为配置不同的源、TTL、要转发的标头和 Lambda@Edge 函数。默认行为匹配所有请求(*),是你的回退。
# Create a CloudFront distribution (S3 origin)
aws cloudfront create-distribution --distribution-config file://cf-config.json
# cf-config.json (simplified)
{
"Origins": {
"Quantity": 1,
"Items": [{
"Id": "S3Origin",
"DomainName": "my-app-bucket.s3.amazonaws.com",
"S3OriginConfig": { "OriginAccessIdentity": "" }
}]
},
"DefaultCacheBehavior": {
"TargetOriginId": "S3Origin",
"ViewerProtocolPolicy": "redirect-to-https",
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
"Compress": true
},
"CacheBehaviors": {
"Quantity": 1,
"Items": [{
"PathPattern": "/api/*",
"TargetOriginId": "APIGatewayOrigin",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"ViewerProtocolPolicy": "https-only"
}]
},
"PriceClass": "PriceClass_100",
"HttpVersion": "http2and3",
"IsIPV6Enabled": true
}缓存失效
更新内容时,可能需要使 CloudFront 缓存失效。每月前 1,000 个失效路径免费;后续每个收费 $0.005。使用版本化文件名(app.v2.js)代替失效操作,以获得更好的缓存控制。
# Invalidate specific files
aws cloudfront create-invalidation \
--distribution-id EDFDVBD6EXAMPLE \
--paths "/index.html" "/app.js"
# Invalidate all files (expensive if > 1000 paths/month)
aws cloudfront create-invalidation \
--distribution-id EDFDVBD6EXAMPLE \
--paths "/*"
# Better: Use versioned asset names (no invalidation needed)
# app.abc123.js <- content hash in filename
# styles.def456.css
# Only invalidate index.html (the entry point)VPC:虚拟私有云
VPC 是你在 AWS 内的私有隔离网络。每个 AWS 账户都有一个默认 VPC。对于生产工作负载,创建具有适当子网分段的自定义 VPC。
公有子网 vs 私有子网
公有子网有通往互联网网关的路由,用于需要直接互联网访问的资源(负载均衡器、堡垒主机)。私有子网没有直接互联网路由,用于数据库、应用服务器和 Lambda 函数。私有子网可以通过公有子网中的 NAT 网关访问互联网(用于 IPv4)。
# Create a VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16
# Create public subnets (one per AZ)
aws ec2 create-subnet \
--vpc-id vpc-0abc123 \
--cidr-block 10.0.1.0/24 \
--availability-zone us-east-1a
aws ec2 create-subnet \
--vpc-id vpc-0abc123 \
--cidr-block 10.0.2.0/24 \
--availability-zone us-east-1b
# Create private subnets
aws ec2 create-subnet \
--vpc-id vpc-0abc123 \
--cidr-block 10.0.11.0/24 \
--availability-zone us-east-1a
# Create Internet Gateway (for public subnets)
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway \
--vpc-id vpc-0abc123 \
--internet-gateway-id igw-0abc123
# Create NAT Gateway in public subnet (for private subnet outbound)
# First, allocate an Elastic IP
aws ec2 allocate-address --domain vpc
aws ec2 create-nat-gateway \
--subnet-id subnet-public-1a \
--allocation-id eipalloc-0abc123
# Add default route to private route table via NAT Gateway
aws ec2 create-route \
--route-table-id rtb-private \
--destination-cidr-block 0.0.0.0/0 \
--nat-gateway-id nat-0abc123NACL vs 安全组
网络 ACL 在子网级别运行,是无状态的:必须显式允许入站和出站规则。安全组在实例级别运行,是有状态的。使用安全组作为主要控制;在需要额外子网级别保护时使用 NACL。
CloudFormation:基础设施即代码
CloudFormation 允许使用 JSON 或 YAML 模板配置 AWS 资源。它管理资源依赖关系,支持失败时回滚,并支持基础设施版本控制。它是 AWS 原生 IaC 工具;替代方案包括 CDK(TypeScript/Python)、Terraform 和 Pulumi。
# CloudFormation template: S3 bucket + Lambda + API Gateway
AWSTemplateFormatVersion: "2010-09-09"
Description: "Serverless API stack"
Parameters:
Environment:
Type: String
AllowedValues: [dev, staging, production]
Default: dev
Resources:
# S3 bucket for uploads
UploadsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "uploads-${Environment}-${AWS::AccountId}"
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
# Lambda execution role
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal: { Service: lambda.amazonaws.com }
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: S3Access
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: [s3:GetObject, s3:PutObject]
Resource: !Sub "${UploadsBucket.Arn}/*"
# Lambda function
ApiFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub "api-handler-${Environment}"
Runtime: nodejs20.x
Handler: dist/index.handler
Role: !GetAtt LambdaRole.Arn
Timeout: 30
MemorySize: 256
Environment:
Variables:
BUCKET_NAME: !Ref UploadsBucket
ENV: !Ref Environment
Outputs:
BucketName:
Value: !Ref UploadsBucket
FunctionArn:
Value: !GetAtt ApiFunction.Arn
# Deploy the stack
aws cloudformation deploy \
--template-file template.yml \
--stack-name my-serverless-api \
--parameter-overrides Environment=production \
--capabilities CAPABILITY_IAMAWS CLI:关键命令和配置文件
AWS CLI 对于自动化、脚本编写和日常操作至关重要。使用 pip 或包管理器安装,配置配置文件,并在脚本和 CI/CD 流水线中使用。
# Install AWS CLI v2
# macOS
brew install awscli
# Linux
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
# --- Configure profiles ---
# Interactive setup (asks for key ID, secret, region, output format)
aws configure
# Configure a named profile
aws configure --profile production
# ~/.aws/credentials
# [default]
# aws_access_key_id = AKIAIOSFODNN7EXAMPLE
# aws_secret_access_key = wJalrXUtnFEMI/K7MDENG...
# [production]
# aws_access_key_id = AKIAI...
# aws_secret_access_key = ...
# ~/.aws/config
# [default]
# region = us-east-1
# output = json
# [profile production]
# region = us-east-1
# role_arn = arn:aws:iam::123456789012:role/ProductionRole
# source_profile = default
# Use a specific profile
aws s3 ls --profile production
AWS_PROFILE=production aws ec2 describe-instances
# --- Essential commands ---
# EC2
aws ec2 describe-instances --query "Reservations[].Instances[].[InstanceId,State.Name,Tags[?Key==Name].Value|[0]]" --output table
aws ec2 start-instances --instance-ids i-0abc123
aws ec2 stop-instances --instance-ids i-0abc123
# S3
aws s3 ls s3://my-bucket/ --recursive --human-readable --summarize
aws s3 rm s3://my-bucket/old-file.txt
aws s3 mv s3://src/file.txt s3://dest/file.txt
# Lambda
aws lambda list-functions --query "Functions[].[FunctionName,Runtime,LastModified]" --output table
aws lambda invoke --function-name my-fn --payload "{\"test\":true}" response.json
# CloudWatch Logs
aws logs tail /aws/lambda/my-fn --follow
aws logs filter-log-events \
--log-group-name /aws/lambda/my-fn \
--filter-pattern "ERROR"
# SSM Parameter Store (store secrets securely)
aws ssm put-parameter \
--name "/myapp/prod/db-password" \
--value "supersecret" \
--type SecureString
aws ssm get-parameter \
--name "/myapp/prod/db-password" \
--with-decryption \
--query "Parameter.Value" --output textAWS vs GCP vs Azure:服务对比
以下是三大主要云提供商等效服务的对比。
| Service Category | AWS | Google Cloud (GCP) | Microsoft Azure |
|---|---|---|---|
| Virtual Machines | EC2 | Compute Engine | Virtual Machines |
| Object Storage | S3 | Cloud Storage (GCS) | Azure Blob Storage |
| Serverless Functions | Lambda | Cloud Functions / Cloud Run | Azure Functions |
| Managed Kubernetes | EKS | GKE | AKS |
| Managed MySQL/Postgres | RDS Aurora | Cloud SQL | Azure Database for PostgreSQL |
| NoSQL Database | DynamoDB | Firestore / Bigtable | Cosmos DB |
| CDN | CloudFront | Cloud CDN | Azure CDN / Front Door |
| DNS | Route 53 | Cloud DNS | Azure DNS |
| Message Queue | SQS | Cloud Pub/Sub | Azure Service Bus |
| Event Streaming | Kinesis | Pub/Sub Lite / Dataflow | Azure Event Hubs |
| Container Registry | ECR | Artifact Registry (GCR) | Azure Container Registry |
| Identity / Auth | Cognito | Firebase Auth / Identity Platform | Azure Active Directory B2C |
| API Gateway | API Gateway | Apigee / Cloud Endpoints | Azure API Management |
| Infrastructure as Code | CloudFormation / CDK | Deployment Manager / Config Connector | ARM / Bicep |
| Monitoring | CloudWatch | Cloud Monitoring + Logging | Azure Monitor |
| Secret Management | Secrets Manager | Secret Manager | Azure Key Vault |
| ML/AI Platform | SageMaker | Vertex AI | Azure Machine Learning |
| Data Warehouse | Redshift | BigQuery | Azure Synapse Analytics |
| VPN / Private Network | VPC + Direct Connect | VPC + Dedicated Interconnect | VNet + ExpressRoute |
成本优化技巧
如果不进行仔细管理,AWS 成本可能会迅速上涨。这些策略将帮助你控制账单。
- 调整 EC2 实例大小:使用 AWS Compute Optimizer 建议。超大实例是最常见的浪费来源。
- 对可预测的工作负载使用节省计划或预留实例:1 年无预付节省 30-40%,3 年节省高达 72%。
- 对访问模式不可预测的对象启用 S3 智能分层——它会自动将数据移动到最便宜的层。
- 对容错工作负载(批处理、CI/CD、ML 训练)使用 Spot 实例——最高节省 90%。
- 立即设置 AWS Budgets 和 CloudWatch 账单警报。一个被遗忘的 EC2 实例每月可能花费数百美元。
- 删除未使用的弹性 IP 地址、未附加的 EBS 卷和空闲负载均衡器——即使未使用也会收费。
- 使用 CloudFront 降低 EC2/S3 的数据传输成本——CloudFront 到互联网比 EC2 到互联网更便宜。
- 为开发数据库启用 RDS 自动停止——在一段时间不活动后自动停止,避免空闲费用。
# Set up a billing alert at $50
aws cloudwatch put-metric-alarm \
--alarm-name "AWS-Billing-50-USD" \
--alarm-description "Alert when estimated charges exceed $50" \
--namespace "AWS/Billing" \
--metric-name "EstimatedCharges" \
--statistic Maximum \
--dimensions Name=Currency,Value=USD \
--period 86400 \
--evaluation-periods 1 \
--threshold 50 \
--comparison-operator GreaterThanOrEqualToThreshold \
--alarm-actions arn:aws:sns:us-east-1:123456789012:billing-alerts
# Note: Billing metrics only exist in us-east-1!
# aws cloudwatch put-metric-alarm --region us-east-1 ...
# Find idle/unused EC2 instances (< 5% CPU over 7 days)
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-0abc123 \
--start-time 2026-02-20T00:00:00Z \
--end-time 2026-02-27T00:00:00Z \
--period 86400 \
--statistics Average
# List unattached EBS volumes (potential waste)
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query "Volumes[].[VolumeId,Size,CreateTime]" \
--output table
# List unused Elastic IPs (cost $0.005/hour if unattached)
aws ec2 describe-addresses \
--query "Addresses[?AssociationId==null].[AllocationId,PublicIp]" \
--output table常见问题
EC2 和 Lambda 有什么区别?
EC2 提供你管理的虚拟机(操作系统、依赖项、扩展)。Lambda 是无服务器的:你只写代码,AWS 处理基础设施。EC2 更适合长期运行的进程、有状态工作负载以及需要特定系统配置的场景。Lambda 更适合事件驱动的短暂任务,以及希望零基础设施管理和按使用量付费计费的场景。
什么时候应该使用 DynamoDB vs RDS?
在以下情况使用 DynamoDB:需要大规模(每秒数百万请求)、个位数毫秒延迟、灵活模式,或者访问模式可预测且可以用分区键+排序键建模。在以下情况使用 RDS:需要复杂查询和连接、跨多个表的 ACID 事务、熟悉的 SQL 接口,或者查询模式复杂且是临时性的。
在 AWS 上运行静态网站的最便宜方式是什么?
S3 静态网站托管 + CloudFront CDN。将 HTML/CSS/JS 上传到 S3 存储桶,启用静态托管,创建指向 S3 的 CloudFront 分发,并使用 Route 53 配置域名。这种设置对于低流量网站每月只需几美分,且无需任何服务器即可扩展到数百万用户。S3 免费套餐包括每月 5GB 存储和 20,000 次 GET 请求。
IAM 角色如何为 EC2 实例工作?
将 IAM 角色附加到 EC2 实例时,实例元数据服务(IMDS)向实例上运行的应用程序提供临时凭证。AWS SDK 自动从 http://169.254.169.254/latest/meta-data/iam/security-credentials/ 读取这些凭证——你无需设置任何环境变量或配置文件。凭证会自动轮换。永远不要在应用程序代码或 EC2 用户数据中放置 AWS 访问密钥。
CloudFront 和负载均衡器有什么区别?
CloudFront 是内容分发网络(CDN),在全球边缘位置缓存内容,减少地理分布用户的延迟并减少源服务器负载。应用程序负载均衡器(ALB)在区域内跨多个后端服务器分配流量以实现可用性和可扩展性。两者配合使用:CloudFront 在 ALB 前面实现全球缓存+区域负载均衡。CloudFront 不能替代负载均衡器。
S3 预签名 URL 是如何工作的?
预签名 URL 是查询字符串中嵌入了身份验证参数(签名、到期时间、访问密钥 ID)的 URL。当客户端请求此 URL 时,S3 验证签名和到期时间,无需客户端提供任何 AWS 凭证。这是以下场景的标准模式:用户文件上传(预签名 PUT)、安全文件下载(预签名 GET)以及第三方访问私有对象而不公开存储桶。预签名 URL 在配置的持续时间后过期(15 分钟到 7 天)。
VPC 对等互连是什么,什么时候需要它?
VPC 对等互连在两个 VPC 之间创建私有网络连接,允许任一 VPC 中的资源使用私有 IP 地址进行通信,就好像它们在同一网络中一样。当你在不同 VPC 中有需要私下通信的资源时需要它——例如,共享服务 VPC(包含数据库、监控)连接到多个应用程序 VPC。对等互连不支持传递路由:如果 A 与 B 对等,B 与 C 对等,A 无法通过 B 到达 C。
AWS 免费套餐是什么,有哪些限制?
AWS 免费套餐有三种类型:12 个月免费(新账户:每月 750 小时 t2.micro EC2、5GB S3、25GB DynamoDB、750 小时 RDS db.t2.micro)、永久免费(Lambda:每月 100 万次请求;DynamoDB:25GB;CloudFront:1TB 数据传出;SNS:100 万次发布)和试用版(较新服务的限时免费试用)。注意:免费套餐不涵盖所有服务,超出限制将产生费用。始终设置账单警报。