04 · AWS 核心服务¶
官方文档:https://docs.aws.amazon.com/ AWS Console:https://console.aws.amazon.com/ 定价计算器:https://calculator.aws/ iGaming 重点:高可用 Multi-AZ · 自动扩容 · 低延迟 · 成本优化
1. VPC 网络设计(基础)¶
标准 iGaming VPC 架构¶
VPC: 10.0.0.0/16
│
├── 可用区 A(ap-southeast-1a)
│ ├── 公有子网 10.0.1.0/24 ← ALB、NAT Gateway、Bastion
│ ├── 私有子网 10.0.10.0/24 ← EC2 应用服务器
│ └── 数据子网 10.0.20.0/24 ← RDS、ElastiCache(最严格隔离)
│
├── 可用区 B(ap-southeast-1b)
│ ├── 公有子网 10.0.2.0/24
│ ├── 私有子网 10.0.11.0/24
│ └── 数据子网 10.0.21.0/24
│
└── 路由规则
公有子网 → Internet Gateway(0.0.0.0/0)
私有子网 → NAT Gateway(出口)
数据子网 → 仅内部通信,无外网出口
Terraform 创建标准 VPC¶
# 官方 VPC 模块:https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "igaming-prod"
cidr = "10.0.0.0/16"
azs = ["ap-southeast-1a", "ap-southeast-1b", "ap-southeast-1c"]
private_subnets = ["10.0.10.0/24", "10.0.11.0/24", "10.0.12.0/24"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
database_subnets = ["10.0.20.0/24", "10.0.21.0/24", "10.0.22.0/24"]
enable_nat_gateway = true
single_nat_gateway = false # 生产环境每个 AZ 一个 NAT GW
enable_dns_hostnames = true
}
安全组设计原则¶
# 仅开放必要端口,来源精确到安全组 ID 而非 CIDR
# ALB 安全组
aws ec2 create-security-group --group-name "alb-sg" --description "ALB"
aws ec2 authorize-security-group-ingress --group-id sg-alb \
--protocol tcp --port 443 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id sg-alb \
--protocol tcp --port 80 --cidr 0.0.0.0/0
# App 安全组(只接受来自 ALB 的流量)
aws ec2 authorize-security-group-ingress --group-id sg-app \
--protocol tcp --port 8080 --source-group sg-alb
# RDS 安全组(只接受来自 App 的流量)
aws ec2 authorize-security-group-ingress --group-id sg-rds \
--protocol tcp --port 5432 --source-group sg-app
2. EC2 & Auto Scaling¶
实例类型选择指南¶
通用型(m 系列):应用服务器,均衡 CPU/内存
m7i.large (2C/8G), m7i.xlarge (4C/16G), m7i.2xlarge (8C/32G)
计算密集型(c 系列):赔率计算引擎、高并发 API
c7i.large (2C/4G), c7i.2xlarge (8C/16G)
内存密集型(r 系列):大缓存、数据库
r7i.large (2C/16G), r7i.xlarge (4C/32G)
购买策略:
On-Demand:短期、不可预测,按秒计费
Reserved (1年/3年):稳定基础负载,节省40-60%
Spot:可被中断的批处理任务,节省70-90%(不适合生产 API)
Savings Plans:最灵活的预留折扣
Auto Scaling Group 配置¶
# 官方文档:https://docs.aws.amazon.com/autoscaling/ec2/userguide/
# 创建启动模板
aws ec2 create-launch-template \
--launch-template-name "app-server-template" \
--launch-template-data '{
"ImageId": "ami-0c02fb55956c7d316",
"InstanceType": "m7i.large",
"IamInstanceProfile": {"Name": "app-role"},
"SecurityGroupIds": ["sg-app"],
"UserData": "'$(base64 -w 0 userdata.sh)'"
}'
# 创建 ASG
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name "app-asg" \
--launch-template "LaunchTemplateName=app-server-template,Version=\$Latest" \
--min-size 2 --max-size 20 --desired-capacity 4 \
--vpc-zone-identifier "subnet-private-a,subnet-private-b" \
--target-group-arns "arn:aws:elasticloadbalancing:..."
# 目标跟踪扩容策略(CPU 70% 为目标)
aws autoscaling put-scaling-policy \
--auto-scaling-group-name "app-asg" \
--policy-name "cpu-target-tracking" \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {"PredefinedMetricType": "ASGAverageCPUUtilization"},
"TargetValue": 70.0
}'
3. RDS(关系型数据库)¶
生产配置要点¶
# 官方文档:https://docs.aws.amazon.com/rds/latest/userguide/
# Aurora PostgreSQL(推荐:比标准 PG 快3x,自动故障转移)
aws rds create-db-cluster \
--db-cluster-identifier "igaming-prod" \
--engine aurora-postgresql \
--engine-version "15.4" \
--master-username admin \
--master-user-password "$DB_PASSWORD" \
--db-subnet-group-name "rds-subnet-group" \
--vpc-security-group-ids "sg-rds" \
--backup-retention-period 7 \
--storage-encrypted \
--deletion-protection
# Multi-AZ:自动在另一个 AZ 有 Standby,故障转移 < 60s
# Read Replica:读写分离,把报表/查询分到 Reader Endpoint
连接端点¶
写入(主节点):cluster.cluster-xxx.rds.amazonaws.com
读取(副本):cluster.cluster-ro-xxx.rds.amazonaws.com
单节点:instance.xxx.rds.amazonaws.com
参数调优¶
-- Aurora PostgreSQL 重要参数
max_connections = 1000 -- 最大连接数(配合 PgBouncer)
shared_buffers = 4GB -- 缓冲区(内存的 25%)
work_mem = 64MB -- 排序内存
checkpoint_completion_target = 0.9
4. ElastiCache(Redis)¶
集群模式(生产推荐)¶
# 官方文档:https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/
# 创建 Redis 7 集群(3主3从)
aws elasticache create-replication-group \
--replication-group-id "igaming-redis" \
--replication-group-description "iGaming Redis Cluster" \
--cache-node-type "cache.r7g.large" \
--engine redis \
--engine-version "7.1" \
--num-cache-clusters 3 \
--automatic-failover-enabled \
--multi-az-enabled \
--at-rest-encryption-enabled \
--transit-encryption-enabled \
--auth-token "$REDIS_AUTH_TOKEN" \
--cache-subnet-group-name "redis-subnet-group" \
--security-group-ids "sg-redis"
博彩平台 Redis 使用模式¶
import redis
r = redis.Redis(
host='igaming-redis.xxx.cache.amazonaws.com',
port=6379,
password=os.environ['REDIS_AUTH'],
ssl=True,
decode_responses=True
)
# 1. 实时赔率(短 TTL,频繁更新)
r.setex(f"odds:{match_id}:{market}", 5, json.dumps(odds_data)) # 5秒过期
# 2. Pub/Sub 推送赔率变化
# 发布端
r.publish('odds-channel', json.dumps({'match': match_id, 'odds': new_odds}))
# 订阅端(WebSocket 服务)
pubsub = r.pubsub()
pubsub.subscribe('odds-channel')
# 3. 用户 Session(30分钟过期)
r.setex(f"session:{session_id}", 1800, json.dumps(user_data))
# 4. 速率限制计数器
count = r.incr(f"ratelimit:{ip}:{minute}")
r.expire(f"ratelimit:{ip}:{minute}", 60)
if count > 60:
raise RateLimitExceeded()
5. ALB 负载均衡¶
# 官方文档:https://docs.aws.amazon.com/elasticloadbalancing/latest/application/
# 创建 ALB
aws elbv2 create-load-balancer \
--name "igaming-alb" \
--type application \
--subnets subnet-public-a subnet-public-b \
--security-groups sg-alb
# 创建目标组(HTTP/2 + 健康检查)
aws elbv2 create-target-group \
--name "app-targets" \
--protocol HTTP --port 8080 \
--vpc-id vpc-xxx \
--health-check-path "/health" \
--health-check-interval-seconds 10 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 3
# 监听规则(基于路径路由)
# /api/odds/* → 赔率服务
# /api/bet/* → 投注服务
# / → 前端服务
ALB 访问日志分析¶
# 启用访问日志到 S3
# 分析慢请求
aws s3 cp s3://alb-logs/AWSLogs/... - | zcat | \
awk '{if ($5 > 1000) print $0}' | head -20 # 响应时间 >1000ms 的请求
6. S3 对象存储¶
# 官方文档:https://docs.aws.amazon.com/s3/latest/userguide/
# 创建桶(最佳实践)
aws s3api create-bucket \
--bucket igaming-assets-prod \
--region ap-southeast-1 \
--create-bucket-configuration LocationConstraint=ap-southeast-1
# 开启版本控制
aws s3api put-bucket-versioning \
--bucket igaming-assets-prod \
--versioning-configuration Status=Enabled
# 生命周期策略(自动归档旧数据)
aws s3api put-bucket-lifecycle-configuration \
--bucket igaming-logs-prod \
--lifecycle-configuration file://lifecycle.json
# lifecycle.json: 30天 → IA, 90天 → Glacier, 365天 → 删除
# 阻止公开访问(非静态网站桶)
aws s3api put-public-access-block \
--bucket igaming-assets-prod \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
7. IAM 最佳实践¶
# 官方文档:https://docs.aws.amazon.com/IAM/latest/UserGuide/
# EC2 实例 Role(应用用这个,不要用 Access Key)
aws iam create-role \
--role-name "app-server-role" \
--assume-role-policy-document file://ec2-trust-policy.json
# 附加策略
aws iam attach-role-policy \
--role-name "app-server-role" \
--policy-arn "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
# 创建自定义策略(最小权限)
aws iam create-policy \
--policy-name "app-custom-policy" \
--policy-document file://custom-policy.json
# 强制 MFA(管理员账号)
aws iam create-policy --policy-name "enforce-mfa" --policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"NotAction": ["iam:CreateVirtualMFADevice","iam:EnableMFADevice","iam:GetUser"],
"Resource": "*",
"Condition": {"BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}}
}]
}'
8. CloudWatch 监控¶
# 官方文档:https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/
# 创建告警(CPU > 80%)
aws cloudwatch put-metric-alarm \
--alarm-name "high-cpu" \
--alarm-description "CPU usage above 80%" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=InstanceId,Value=i-xxx \
--evaluation-periods 2 \
--alarm-actions "arn:aws:sns:region:account:alert-topic"
# 自定义指标(应用层指标)
aws cloudwatch put-metric-data \
--namespace "iGaming/App" \
--metric-name "ActiveBets" \
--value 1234 \
--unit Count
# CloudWatch Logs Insights 查询(快速分析日志)
aws logs start-query \
--log-group-name "/app/production" \
--start-time $(date -d '1 hour ago' +%s) \
--end-time $(date +%s) \
--query-string 'fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc | limit 50'
官方文档 & 学习资源¶
| 资源 | 链接 |
|---|---|
| AWS 文档总入口 | https://docs.aws.amazon.com/ |
| AWS Well-Architected | https://aws.amazon.com/architecture/well-architected/ |
| AWS CLI 文档 | https://awscli.amazonaws.com/v2/documentation/api/latest/index.html |
| Terraform AWS Provider | https://registry.terraform.io/providers/hashicorp/aws/latest/docs |
| AWS 博彩架构参考 | https://docs.aws.amazon.com/architecture-diagrams/latest/sports-betting-architecture/ |
| AWS SAA 备考(Stephane Maarek) | https://www.udemy.com/course/aws-certified-solutions-architect-associate-saa-c03/ |
| TutorialsDojo 练习题 | https://tutorialsdojo.com/ |
| LocalStack(本地模拟 AWS) | https://github.com/localstack/localstack |
常见问题 & 坑¶
Q: RDS 连接数耗尽(too many connections)? A: 在 EC2 和 RDS 之间加 PgBouncer(PostgreSQL)或 ProxySQL(MySQL)做连接池;Lambda 场景用 RDS Proxy
Q: Auto Scaling 扩容了但请求还是超时?
A: 检查 ALB Target Group 健康检查是否通过;新实例 warmup 时间是否配置(DefaultInstanceWarmup)
Q: S3 出口流量费用高? A: 使用 Cloudflare R2(S3 兼容,无出口费用)替代 S3 存储静态资源;或 CloudFront 在前面做缓存
Q: EC2 实例突然无法访问?
A: 检查顺序:1.安全组入站规则 2.NACL 规则 3.路由表 4.实例状态 5.系统日志(get-console-output)
最后更新:2025-04