返利机器人的Serverless实践:基于阿里云函数计算(FC)的低成本自动化任务调度
返利机器人的Serverless实践:基于阿里云函数计算(FC)的低成本自动化任务调度
大家好,我是阿可,微赚淘客系统及省赚客APP创始人,是个冬天不穿秋裤,天冷也要风度的程序猿!
一、业务痛点:常驻ECS浪费钱
省赚客返利机器人需要24h监听电商平台订单状态,每天峰值集中在10、15、20点,其余时段CPU<5%。
原架构:4台2C4G ECS+Quartz,月账单¥712。
目标:
- 按调用付费,闲时0元;
- 毫秒级弹性,峰值6k并发不排队;
- 代码零改造,SpringBoot一键移植。
二、技术选型:阿里云函数计算3.0
- 支持Java17、SpringBoot2.7+、自定义Runtime;
- 单实例并发度100,冷启动<600ms(VPC预热后<150ms);
- 内置日志、监控、灰度、VPC、NAS、定时触发、EventBridge,无需自建运维。

三、函数结构设计
cn.juwatech
├── RobotApplication.java
├── handler
│ ├── OrderSyncHandler.java // 订单同步函数
│ ├── CommissionCalcHandler.java // 分佣计算函数
│ └── PushHandler.java // 用户推送函数
├── service
│ └── OrderService.java
└── model
└── Order.java
单函数单职责,方便独立灰度与权限。
四、入口函数:FC Custom Runtime
package cn.juwatech.handler;
import cn.juwatech.service.OrderService;
import com.alibaba.fastjson2.JSON;
import com.aliyun.fc.runtime.*;
import java.io.IOException;
import java.io.OutputStream;
public class OrderSyncHandler implements StreamRequestHandler {
private static final OrderService orderService = new OrderService();
@Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
FcLogger logger = context.getLogger();
String json = new String(input.readAllBytes());
logger.info("receive event: " + json);
long orderId = JSON.parseObject(json).getLong("orderId");
boolean ok = orderService.sync(orderId);
output.write(JSON.toJSONBytes(Map.of("success", ok)));
}
}
打包bootstrap:
#!/usr/bin/env bash
java -cp .:lib/* cn.juwatech.handler.OrderSyncBootstrap
上传ZIP即可。
五、Serverlessless定时触发:Cron表达式
YAML模板:
TypeAliyun::Serverless::Function
Properties:
Handler: cn.juwatech.handler.OrderSyncHandler
Runtime: custom
MemorySize: 512
InstanceConcurrency: 100
Events:
timer:
Type: Timer
Properties:
CronExpression: '0 0/10 * * * *' # 每10分钟
Enable: true
闲时无调用,定时触发同样按次计费,百次≈¥0.02。
六、分层解耦:EventBridge总线
订单同步后发送自定义事件,佣金计算函数订阅:
Event.put("source","robot.order","type":"OrderFinished","data":orderJson);
EventBridge规则:
{
"source": ["robot.order"],
"type": ["OrderFinished"]
}
佣金函数异步执行,平均延迟80ms,单实例并发100,峰值6k QPS无冷启动。
七、推送函数:对接钉钉+微信
public class PushHandler implements StreamRequestHandler {
public void handleRequest(InputStream input, OutputStream output, Context context) {
String body = new String(input.readAllBytes());
PushEvent evt = JSON.parseObject(body, PushEvent.class);
switch (evt.getChannel()){
case "dingtalk" -> DingSender.send(evt);
case "wechat" -> WxSender.send(evt);
}
}
}
单用户单并发,防止API限流,FC自动重试3次,失败进DLQ。
八、环境变量+密钥托管
数据库密码、AppKey全部写到FC“环境变量”与“密钥管理”,代码零hardcode:
String dbPwd = System.getenv("DB_PWD");
函数无状态,密钥轮转10秒级生效。
九、性能调优:冷启动<150ms
- VPC预热:配置
initializer,函数启动即预热连接池; - 精简JAR:SpringBoot瘦身,仅保留必要starter,lib体积从68MB→23MB;
- 单实例多并发:Memory512MB+Concurrency100,比128MB×1并发成本降70%;
- 快照加速:打开
instanceLifecycleConfig.preFreeze=true,快照后冷启动缩短40%。
十、成本对比
| 资源 | ECS常驻(月) | FC Serverless(月) |
|---|---|---|
| 计算 | 4台2C4G ¥712 | 调用1千万次 ¥95 |
| 公网 | 带宽5M ¥115 | 函数出流量100GB ¥21 |
| 运维 | 人力30% | 0 |
| 合计 | ¥827 | ¥116 |
节省86%,大促高峰(1.2亿次)自动弹性,未超¥200。
十一、可观测:日志+指标+链路
日志:函数打印到SLS,关键字告警;
指标:FC内置QPS、Latency、ErrorRate,Grafana插件直接拉取;
链路:ARMS探针arms-agent-1.0.zip,函数启动参数加-javaagent,Trace与ECS侧打通,完整看到FC→RDS→Redis耗时。
十二、灰度与回滚
别名+权重:
aliyun fc update-alias --service-name robot --alias-name prod --version-id 3 --weight 20
先灰20%流量,错误率>1%立即--weight 0全回滚,30秒生效。
十三、CICD:GitHub Actions一键部署
- name: Deploy to FC
uses: aliyun/fc-deploy-action@v3
with:
access-key-id: ${{ secrets.ACCESS_KEY_ID }}
access-key-secret: ${{ secrets.ACCESS_KEY_SECRET }}
template: serverless.yml
master分支push→单元测试→maven package→自动部署,全程2分钟。
十四、踩坑记录
- 自定义Runtime未加
#!/bin/bash,触发exec format error; - 函数内写日志到
/tmp,下次调用被清理,改为直接打印标准输出; - SpringBoot懒加载+反射,首次请求RT 3s,加入
spring.main.lazy-initialization=false预热; - VPC网段冲突,函数访问RDS超时,切换至FC专用vSwitch并加白名单;
- 定时触发器Cron最小粒度1分钟,业务需30秒轮询,改用EventBridge+循环发送解决。
十五、后续规划
- 将图片下载、压缩、OCR识别拆分为三个函数,串成工作流,单图片成本<¥0.001;
- 采用FC GPU实例,做实时优惠券封面生成,预计节省60%设计外包费;
- 接入阿里云Serverless工作流,订单对账多函数编排,失败自动重试与人工审批。
本文著作权归聚娃科技省赚客app开发者团队,转载请注明出处!
更多推荐


所有评论(0)