先交代一件让自己脸红的事。
我有一台 ECS,买它的理由特别朴素——每天凌晨三点跑一次备份脚本。脚本本身跑多久?三十秒。剩下那二十三小时五十九分半,它在干什么?在发呆。监控图上的 CPU 曲线平得像是心电图忘了插电,内存常年占着一小块不动如山,唯一活跃的是系统日志里那些"我还在"的呼吸声。
就这么一个每天上班三十秒的活,我按月给它开工资,还得记着给它打补丁。直到有一天我数了数手里这类"电子宠物"——定时清理、定时抓取、定时推送、一个给朋友小工具用的 webhook 接口——四台,每台都在重复同一种浪费。
后来我把它们全都搬到了函数计算上。这篇文章就讲这次搬家:什么场景下"不要服务器"这件事真的成立,以及搬的过程中有哪些坑是我实打实踩过的。
一、函数计算到底把什么拿走了
官方的定义是:事件驱动的全托管 Serverless 计算服务,你不用管理服务器等基础设施,只编写代码并上传,平台负责准备计算资源并弹性、可靠地运行。
翻译成人话:以前你写一段脚本,得先回答"它跑在哪台机器上";现在这个问题被平台替你回答了,你只需要回答"它被什么触发"。
这句话的差别比看上去大。因为"跑在哪台机器上"后面跟着一串你不想承认的隐性工作量:机器规格、系统镜像、运行环境、依赖版本、扩容策略、宕机了谁拉起来、怎么打补丁。函数计算把这些整包收走,顺带附赠多可用区自动容灾(官方页面标注 SLA 99.95%),你不用为冗余资源额外掏钱。
二、三种最香的用法
1. 定时脚本(Cron)
最典型的一类。触发器配一条 Cron 表达式,比如每天凌晨三点,函数被调用一次,跑完就释放。签退比你还准时。
适合:数据备份、定时抓取、报表生成、到期提醒、清理临时文件。
2. HTTP 接口
给函数挂一个 HTTP 触发器,它就是一个能公网访问的接口。小工具、webhook 回调、第三方消息转发、内部系统的轻量查询接口,都能这么干。再绑个自定义域名,对外就是正规 API。
这类需求以前的标准答案是"买台最低配的机器挂着"。现在答案是"写个函数,没人调它的时候它不花你钱"。
3. 事件驱动
函数计算支持丰富的事件源,官方场景里列得很清楚:对 OSS 里上传的 zip 包做解压、对 SLS 日志做清洗、消费 MNS 消息、视频转码、AI 推理服务。
这一类才是 Serverless 真正的舒适区——流量是突发且不可预测的。你不知道用户什么时候传文件、什么时候来一波日志,常驻一台机器去等,等的就是浪费。
三、最小可用实操:一个 Python 函数长什么样
以 Python 为例,函数入口就是这样的签名:
def handler(event, context):
# event 里是触发事件的内容,定时触发时通常是 JSON 字符串
# context 里是运行环境信息:请求 ID、函数配置、临时密钥等
print("干活了")
return "done"
真正要留心的不是这段代码,是它周围的四件事:
- 依赖怎么带:第三方库不会凭空出现在运行环境里。要么和代码一起打包上传,要么用"层"单独管理,别指望在控制台里 pip install。
- 超时时间:默认是有上限的,跑批任务先想清楚最坏耗时,别让一个两分钟的任务卡在默认超时上(具体上限以官方页面的实时说明为准)。
- 日志去哪看:函数跑完进程就没了,
print的内容不会留在某台机器上等你 SSH 进去看。日志要接到日志服务里查,这是唯一可靠的回溯手段。 - 临时目录:函数实例有
/tmp可用,但它是临时的。别把状态存在本地文件里,要持久化就写 OSS 或数据库。
四、冷启动:迟早要面对的一个词
函数在一段时间没人调用之后,平台会回收它的运行实例;下一次请求来,要重新拉起环境——这段时间就是冷启动。表现是:某一个请求突然比平时慢不少。
官方页面给的解法是弹性实例 + 常驻实例两条腿:弹性实例应对突发流量,常驻实例消除冷启动。
怎么选,看你的延迟容忍度:
- 后台任务、定时脚本:冷启动完全无所谓。多等几百毫秒,反正也没人盯着。
- 对外的同步接口:延迟敏感就得考虑常驻/预留,让实例一直在那儿等着。你要为"随叫随到"付一点钱,换掉那个偶发的慢请求。
- 突发型业务:两种搭配着用,常态用弹性省成本,高峰前把常驻顶上去。
弹性与常驻的具体规格和计费差异,对着函数计算 FC 产品页的实时说明确认一遍再定,别照着旧文章的记忆下单。
五、算账:什么情况下它便宜,什么情况下它反而贵
这里我说句公道话——函数计算不是所有场景都省钱,别把它当万能膏药。
它划算的场景:
- 调用稀疏(比如一天几次、一小时几次),机器闲着的时间远多于干活的时间
- 流量波峰波谷差距大,波峰来了要能瞬间扩上去
- 任务短小、无状态、跑完即走
它不划算的场景:
- 7×24 满载跑、CPU 长期高位:这时候按资源使用量计费,不如直接包一台机器来得稳
- 单次执行时间特别长的重任务:按执行时长计费,跑得越久账单越长
- 需要常驻大内存、大量本地缓存、或者依赖特殊系统环境的老程序:改造成本可能比省下的钱高
我的那四台"电子宠物",每一台都精准命中"划算"那一栏:调用稀疏、任务短小、跑完即走。账单变化我不报具体数字(不同规格、不同调用量的账不一样,以官方页面的实时展示为准),但工作量的变化是实打实的——四台机器的系统维护、补丁、监控告警,一夜之间全部消失。
六、避坑清单(搬之前照着检查一遍)
- [ ] 函数是短任务模型:别在里面跑需要几十分钟的长流程,超长任务考虑拆分或换方案
- [ ] 别指望本地磁盘:
/tmp是临时的,实例回收就没了,持久化走 OSS/数据库 - [ ] 依赖打包要和运行环境一致:本地是 x86 的 Mac、运行环境是 Linux x86_64,涉及编译的包别直接拷,用官方推荐的打包方式或层
- [ ] 访问 RDS / OSS 等云产品要配网络:函数默认不能随便访问你的内网资源,需要配置 VPC 和对应的 RAM 角色,按最小权限原则授权
- [ ] 并发要设上限:不加限制的话,一次突发可能把下游数据库直接压垮,函数扩得比数据库快得多
- [ ] 超时和内存规格一起调:内存规格影响 CPU 分配,卡在性能上不一定是你的代码写得差
- [ ] 先看日志再改代码:日志服务里能看到每次调用的请求 ID、耗时、报错,比在本地猜快得多
- [ ] 免费额度与计费细节以官方页面实时为准:别照着任何一篇旧文章(包括这篇)里的数字下单
结语
回到开头那台"每天上班三十秒"的机器。它的问题不是太贵,是我用一台长期在岗的服务器,去干一件根本不需要常驻的活——这是架构选择错了,不是价格谈判输了。
判断标准其实就一句话:这个活儿是不是"等事件"的? 是等一个时间点、等一个 HTTP 请求、等一个文件上传,那它就该住在函数里;如果你的程序需要一直醒着、一直占着内存、一直维持长连接,那老老实实用服务器。
如果你的场景正好卡在"等事件"这一侧,可以从官方页面看看现在的规格、计费方式和免费额度再动手:函数计算 FC 产品页。先拿一个最不重要的定时脚本试水,跑顺一周,再搬第二第三个——我那四个脚本就是这么一个一个搬完的,一次搬一个,出问题也不慌。