Skip to content

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