
现代化改造这词儿这两年太火了,搞得好像你不上Serverless就落伍了一样。但说实话,我见过太多团队把一个本来跑得好好的系统,花了半年改成微服务+无服务器架构,最后账单翻了3倍,排障时间翻了5倍。无服务器、托管服务、自建EC2,到底该怎么选?这事儿没有标准答案,但有一些硬指标可以帮你做判断。
很多文章会告诉你"Serverless按调用付费,省钱!"——这话只对了一半。
Lambda的计费是这样的:每100万次调用,加上每秒0.0000166667的执行时间费用。听起来很便宜对吧?
我给你算一笔账。假设你有一个API,平均每天10万次请求,每次执行时间200ms,分配512MB内存:
月调用次数:3,000,000次
调用费用:3 × $0.20 = $0.60
执行时间:3,000,000 × 0.2s × 0.5GB = 300,000 GB-秒
时间费用:300,000 × $0.0000166667 ≈ $5.00
月总计:约 $5.60这个价格确实很香。一台t3.small EC2一个月大概$15,看起来Lambda完胜。
但这是日均10万请求的场景。如果你的业务涨到日均100万请求呢?
月调用次数:30,000,000次
调用费用:30 × $0.20 = $6.00
执行时间:30,000,000 × 0.2s × 0.5GB = 3,000,000 GB-秒
时间费用:3,000,000 × $0.0000166667 ≈ $50.00
月总计:约 $56.00还行,但这时候一台跑个应用大概30/月就能扛住了。而且EC2可以买Reserved Instance打个六折,变成$18。
成本拐点大概在哪里? 根据我的经验和各种案例对比,当你的workload变得持续且稳定的时候——比如每秒几十个请求以上、一天不怎么有低谷——Lambda的成本优势就开始消失了。
有个哥们做了个真实案例分享:他们把一个计算密集型的后台任务从Lambda迁到EC2 Reserved Instance,月账单从直接降到1790。Lambda账单占原来的22%都不到——因为他们那个任务是持续运行的,Lambda计费模型完全不适合。
ECS Fargate是个很有意思的中间地带。你不用管底层EC2,但你需要管容器镜像、任务定义、网络配置这些。
Fargate的价格比同等规格的EC2大概贵30%-50%。比如说0.25 vCPU + 0.5GB内存的Fargate任务,一个月大概;同样配置你自己开台来跑,按算大概3.8/月。
# Fargate任务定义示例
taskDefinition:
family: my-api
cpu: '256' # 0.25 vCPU
memory: '512' # 0.5 GB
networkMode: awsvpc
containerDefinitions:
- name: api
image: my-registry/my-api:latest
portMappings:
- containerPort: 8080
logConfiguration:
logDriver: awslogs
options:
awslogs-group: /ecs/my-api
awslogs-region: ap-southeast-1
awslogs-stream-prefix: ecs那你为什么还要用Fargate?因为你不用管理EC2实例的生命周期。不用担心OS补丁、不用担心实例被标记为retired要迁移、不用自己配置auto-scaling group。对于一个3-5人的小团队,这些省下来的运维时间是值钱的。
说了半天,到底怎么选?我总结了几个关键的判断维度:
看流量模式:
你的流量是脉冲式的还是持续平稳的?如果你做的是一个每天只有早上9点到10点有人用的报表系统,或者一个处理webhook回调的后台服务,一天可能就几百次调用——用Lambda,不解释,太合适了。
但如果你跑的是一个在线商城的API后端,7×24有稳定请求,那Lambda反而可能是最贵的选择。
看团队能力:
这个很多人不愿意承认。如果你团队里没人会管Linux、没人会调Nginx配置、没人会处理EC2磁盘满了或者内存泄漏——那自建EC2对你来说就是个坑。你省下来的机器费用,会在凌晨3点的告警里加倍还回来。
反过来说,如果你团队有两三个靠谱的运维或者SRE,EC2的可控性和成本优势是很明显的。
看你需要多少控制权:
Lambda有硬限制:单次执行最长15分钟,内存最大10GB,包大小有限制(解压后250MB),冷启动延迟不可控。如果你的业务需要跑一个30分钟的ETL任务、需要加载一个大模型做推理、需要连接特殊的硬件(GPU)——Lambda直接出局。
Fargate也有限制:你拿不到底层主机的控制权,不能用特权模式的容器,不能用自定义AMI。需要GPU?对不起,得用EC2。
┌─────────────────────────────────────────────────────────┐
│ 选型决策简易流程 │
├─────────────────────────────────────────────────────────┤
│ │
│ 你的任务能在15分钟内跑完吗? │
│ ├─ 否 → 排除Lambda │
│ └─ 是 → 继续 │
│ │
│ 你需要GPU、自定义内核模块、特权容器? │
│ ├─ 是 → EC2 (没得选) │
│ └─ 否 → 继续 │
│ │
│ 你的日均请求量超过100万 且 流量平稳? │
│ ├─ 是 → EC2/ECS on EC2 (成本最优) │
│ └─ 否 → 继续 │
│ │
│ 你的团队有能力管理服务器? │
│ ├─ 否 → Fargate 或 Lambda │
│ └─ 是 → 看你更在意省钱还是省心 │
│ ├─ 省钱 → EC2 │
│ └─ 省心 → Fargate │
│ │
│ 流量波动大?有明显的低谷期? │
│ ├─ 是 → Lambda (按需付费最划算) │
│ └─ 否 → Fargate (容器化+无需管服务器) │
│ │
└─────────────────────────────────────────────────────────┘回到开头那个问题——你的业务是否应该做现代化改造?
我觉得有几个信号可以帮你判断:
该改的信号:
不该改的信号:
我见过一个印象很深的案例。一家做企业SaaS的小公司,原来一台4核8G的EC2跑了三年稳稳当当,后来新CTO来了要"全面云原生改造",搞了Lambda + API Gateway + DynamoDB + SQS + Step Functions一整套。改造花了6个月,团队从5个人招到了8个人,月费用从涨到1800——业务量其实没变。
不是说这架构不好。如果他们后面业务量涨10倍、团队扩到50人,这套架构的弹性和可维护性确实更强。但当下那个阶段,这就是过度工程。
实际生产环境中,很少有人只用一种方案。比较常见的搭配是:
核心API服务 → ECS Fargate 或 EC2(稳定流量,需要低延迟) 异步任务/事件处理 → Lambda(图片处理、邮件发送、消息通知) 定时任务 → Lambda + EventBridge(每天跑一次的报表、数据清洗) 数据库 → RDS/Aurora(托管服务,省掉数据库运维) 缓存 → ElastiCache(别自己搭Redis集群,真的) 文件存储 → S3(这个没什么好犹豫的)
# 一个典型的混合架构 CloudFormation 片段
Resources:
# 核心API - 跑在Fargate上,稳定出力
ApiService:
Type: AWS::ECS::Service
Properties:
LaunchType: FARGATE
DesiredCount: 2
# 图片处理 - Lambda搞定,用完即走
ImageProcessor:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.12
Timeout: 300
MemorySize: 1024
Events:
S3Upload:
Type: S3
Properties:
Bucket: !Ref UploadBucket
Events: s3:ObjectCreated:*
# 数据库 - 交给RDS,别自己折腾
Database:
Type: AWS::RDS::DBInstance
Properties:
Engine: postgres
DBInstanceClass: db.t3.medium
MultiAZ: true
BackupRetentionPeriod: 7这种混合方案的好处是,每个组件用最适合它特性的计算模型。核心API需要稳定和低延迟,用Fargate或EC2;异步的后台任务流量不稳定,用Lambda按需计费最划算;数据库这种有状态服务,用托管的省心。
如果你现在正在纠结要不要改造、怎么改造,我建议你先坐下来回答这5个问题:
技术选型没有银弹。Lambda不是银弹,Kubernetes不是银弹,EC2也不是银弹。
我一直觉得,好的架构不是用了多少时髦技术,而是在当前团队能力、业务阶段、预算约束下,做出的最合理的tradeoff。一台$15/月的EC2跑一个够用的服务,并不丢人。用Lambda做一个事件驱动的后台处理,也并不意味着你就"现代化"了。
如果你的系统在稳定运行、成本可控、团队能驾驭——它就已经是一个好架构了。别被焦虑驱动着去做不必要的改造。
当然,如果你确实遇到了扩展瓶颈、运维负担过重、或者业务增长需要更强的弹性——那该改就改,但要渐进式地改,一个模块一个模块来,用数据说话,而不是一上来就推倒重来。