一、可能用到的阿里云产品(最终版)
| 产品 | 用途 | 关键说明 |
|---|---|---|
| 函数计算 FC | 无服务器计算服务,运行下载/上传 Python 代码 | 按调用次数+资源使用量计费,空闲时零成本 |
| 对象存储 OSS | 存放下载的 CSV 文件,供上传函数读取 | 解决 FC 无状态导致的文件共享问题;内网传输免费 |
| 专有网络 VPC | 打通函数与 RDS 的内网安全通道 | 避免数据库暴露在公网 |
| 云数据库 RDS | 存储业务配置及 CSV 成果数据 | 与 FC 同地域,走内网访问 |
| 日志服务 SLS | 记录函数执行日志,用于监控和排障 | FC 自动投递,无需额外开发 |
| 访问控制 RAM | 为函数授予访问 OSS、VPC 等资源的权限 | 通过角色授权,避免硬编码 AK |
| Serverless Devs | 部署工具(YAML 配置) | 一键部署,支持 CI/CD |
二、总体架构与数据流

数据流说明:
下载函数 从 ASP 获取 CSV 内容,不落本地磁盘,直接写入 OSS(以
item_id.csv为键)。上传函数 根据
item_id从 OSS 读取对应的 CSV 内容,解析后存入 RDS。两个函数完全解耦,通过 OSS 共享文件,解决了 FC 实例无状态、无法共享本地磁盘的问题。
三、程序改造核心:从本地文件系统到 OSS
3.1 原有逻辑(本地运行)
python
python
# 下载
csv_path = os.path.join(SAVE_DIR, f"{item_id}.csv")
with open(csv_path, 'w') as f:
f.write(csv_content)
# 上传
csv_path = os.path.join(SAVE_DIR, f"{item_id}.csv")
with open(csv_path, 'r') as f:
data = f.read()
save_to_db(data)
3.2 改造后(FC + OSS)
依赖安装 :oss2(阿里云 OSS SDK)
下载函数(保存到 OSS):
python
python
def download_from_oss(bucket, item_id):
key = f"csv_data/{item_id}.csv"
obj = bucket.get_object(key)
return obj.read().decode('utf-8')
def upload_handler(event, context):
item_id = event['item_id']
# 1. 从 OSS 读取 CSV 内容
creds = context.credentials
auth = Auth(creds.access_key_id, creds.access_key_secret)
bucket = oss2.Bucket(auth, 'oss-cn-hangzhou-internal.aliyuncs.com', 'your-bucket-name')
csv_content = download_from_oss(bucket, item_id)
# 2. 解析并写入 RDS
save_to_db(csv_content, item_id, context)
# 3. (可选)删除 OSS 中的文件,避免冗余
bucket.delete_object(f"csv_data/{item_id}.csv")
return {"status": "imported", "item_id": item_id}
上传函数(从 OSS 读取):
python
python
def download_from_oss(bucket, item_id):
key = f"csv_data/{item_id}.csv"
obj = bucket.get_object(key)
return obj.read().decode('utf-8')
def upload_handler(event, context):
item_id = event['item_id']
# 1. 从 OSS 读取 CSV 内容
creds = context.credentials
auth = Auth(creds.access_key_id, creds.access_key_secret)
bucket = oss2.Bucket(auth, 'oss-cn-hangzhou-internal.aliyuncs.com', 'your-bucket-name')
csv_content = download_from_oss(bucket, item_id)
# 2. 解析并写入 RDS
save_to_db(csv_content, item_id, context)
# 3. (可选)删除 OSS 中的文件,避免冗余
bucket.delete_object(f"csv_data/{item_id}.csv")
return {"status": "imported", "item_id": item_id}
关键变化:
不再依赖本地目录
SAVE_DIR。文件读写全部通过 OSS SDK 完成。
可通过
context.credentials获取临时 AK,无需硬编码。
四、触发方式(怎么调起来)
| 触发方式 | 适用场景 | 配置示例 |
|---|---|---|
| 定时触发器 | 定期执行(如每小时下载,每日上传) | Cron: 0 0 * * * * |
| HTTP 触发器 | 外部系统按需调用,携带 item_id |
POST 请求,Body 为 {"item_id": 123} |
推荐:为下载和上传分别配置独立的定时触发器,可设置不同频率。例如:
-
下载函数:每小时执行一次,拉取最新 CSV。
-
上传函数:每小时执行一次(在下载后 5 分钟),处理新文件。
五、网络与权限配置
5.1 网络配置(VPC + OSS 内网)
| 资源 | 网络要求 | 说明 |
|---|---|---|
| RDS | 只允许 VPC 内网访问 | 在 RDS 控制台将网络类型设置为 VPC |
| FC 函数 | 配置 VPC(与 RDS 相同 VPC) | 同时开启 公网访问(因需访问 ASP 和 OSS) |
| OSS | 使用内网 endpoint | 例如 oss-cn-hangzhou-internal.aliyuncs.com,走内网免费且更快 |
⚠️ FC 配置 VPC 后,默认会失去公网访问能力,需在服务配置中同时勾选 "允许函数访问公网"。
5.2 权限配置(RAM 角色)
为 FC 服务创建角色,并附加以下权限策略:
json
{ "Statement": [ { "Effect": "Allow", "Action": [ "ecs:CreateNetworkInterface", "ecs:DescribeNetworkInterfaces", "ecs:AttachNetworkInterface" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "oss:PutObject", "oss:GetObject", "oss:DeleteObject" ], "Resource": "acs:oss:*:*:your-bucket-name/*" }, { "Effect": "Allow", "Action": [ "rds:DescribeDBInstances", "rds:Modify*" ], "Resource": "*" } ] }
也可以直接使用系统策略:
-
AliyunECSNetworkInterfaceManagementAccess(VPC 访问) -
AliyunOSSFullAccess(或自定义更细粒度的 OSS 权限) -
AliyunRDSReadOnlyAccess/AliyunRDSFullAccess
六、部署步骤(使用 Serverless Devs)
6.1 项目结构
text
fc-ad-project/
├── index.py # 统一入口,根据 event 调用下载或上传逻辑
├── download_module.py # 下载业务逻辑(含 OSS 上传)
├── upload_module.py # 上传业务逻辑(含 OSS 下载)
├── db_utils.py # 数据库连接(使用 VPC 内网地址)
├── requirements.txt # 依赖:oss2, pymysql, requests...
├── s.yaml # Serverless Devs 配置
6.2 关键配置 s.yaml
yaml
edition: 1.0.0 name: fc-ad-project access: "default" services: ad-service: component: fc props: region: cn-hangzhou service: name: ad-data-service internetAccess: true # 访问公网(ASP 和 OSS) vpcConfig: # VPC 内网访问 RDS vpcId: vpc-xxxxx vSwitchIds: [vsw-xxxxx] securityGroupId: sg-xxxxx logConfig: # 日志服务 project: fc-ad-log logstore: ad-logstore role: acs:ram::xxx:role/fc-role # RAM 角色 environmentVariables: OSS_BUCKET: your-bucket-name OSS_ENDPOINT: oss-cn-hangzhou-internal.aliyuncs.com DB_HOST: rm-xxxxx.mysql.rds.aliyuncs.com functions: download-func: name: download-func runtime: python3.9 codeUri: ./ handler: index.handler memorySize: 512 timeout: 300 events: - timerTrigger: name: hourly-download type: timer properties: cronExpression: "0 0 * * * *" # 每小时整点 payload: '{"action":"download"}' upload-func: name: upload-func runtime: python3.9 codeUri: ./ handler: index.handler memorySize: 512 timeout: 300 events: - timerTrigger: name: hourly-upload type: timer properties: cronExpression: "0 5 * * * *" # 每小时过5分 payload: '{"action":"upload"}'
6.3 统一入口 index.py 示例
python
python
import json
import logging
from download_module import run_download
from upload_module import run_upload
def handler(event, context):
logger = logging.getLogger()
if isinstance(event, str):
event = json.loads(event)
action = event.get("action")
item_id = event.get("item_id") # 可从 event 中获取,也可从 DB 查询待处理列表
if action == "download":
return run_download(item_id, context)
elif action == "upload":
return run_upload(item_id, context)
else:
return {"error": "unknown action"}
注意 :如果每次需要处理多个
item_id,可以在函数内遍历查询 DB 获取所有待处理项,逐一处理。
6.4 部署命令
bash
# 安装 Serverless Devs npm install @serverless-devs/s -g # 配置阿里云凭证 s config add # 构建(在容器内安装 Linux 依赖) s build --use-docker # 部署 s deploy
七、迁移检查清单(从本地到 FC+OSS)
| 项目 | 本地模式 | 云上模式(FC + OSS) | 改动点 |
|---|---|---|---|
| 文件存储 | 本地磁盘 SAVE_DIR | OSS 对象存储 | 替换文件读写为 OSS SDK |
| 文件共享 | 同一台机器多进程共享 | 跨实例、跨函数共享 | 通过 OSS 实现 |
| 调度方式 | cron 或手动执行 | 定时触发器 / HTTP 触发器 | 移除 crontab,改用 FC 触发器 |
| 数据库访问 | 直连公网 IP | VPC 内网地址 + 白名单 | 配置 VPC 和安全组 |
| 日志查看 | 本地文件 | 日志服务 SLS | 无需代码改动,自动收集 |
| 密钥管理 | 配置文件或环境变量 | RAM 角色 + context.credentials | 删除硬编码 AK |
| 部署方式 | 手动打包上传 | Serverless Devs 一键部署 | 引入基础设施即代码(IaC) |
八、成本与收益分析
8.1 成本
-
函数计算:每月前 100 万次调用免费;资源使用量约 0.00011 元/GB-秒(极低)。
-
OSS:存储费用 0.12 元/GB/月;内网请求免费;少量 CSV 文件可忽略。
-
日志服务:每月前 500 MB 免费。
-
VPC & RAM:免费。
预估:日均执行 100 次下载+上传,月成本 < 5 元。
8.2 收益
-
零运维:无需管理服务器、无需关心磁盘空间。
-
自动弹性:高并发时自动扩容,空闲时缩容到零。
-
高可用:FC 多可用区容灾,OSS 数据 99.9999999% 持久性。
-
安全合规:数据库不暴露公网,密钥不落地。
九、总结
通过引入 OSS 作为共享存储层,完美解决了 FC 无状态环境下的文件传递问题。改造后的方案:
-
下载函数:ASP → OSS
-
上传函数:OSS → RDS
两个函数可独立调度、独立扩缩容,架构清晰,成本极低。建议您按照本文档的步骤进行 POC 验证,再将生产流量逐步迁移。