基于华为云 FunctionGraph + API 网关构建 Serverless 文件处理流水线
背景与痛点
在传统企业应用中,文件上传后的处理(如格式转换、图片压缩、内容审核、数据提取等)往往依赖一台常驻的服务器或虚拟机。这种模式存在几个突出问题:
-
资源浪费:文件处理是典型的事件驱动型任务,大部分时间服务器处于空闲等待状态,却要持续付费。
-
扩展性差:遇到业务高峰(如促销活动批量上传),处理能力无法快速弹性扩容,容易导致任务积压或服务超时。
-
运维复杂:需要维护操作系统补丁、运行环境、监控告警等,分散了业务开发的精力。
华为云 FunctionGraph(函数工作流)与 API 网关(APIG) 的结合,为上述问题提供了一个优雅的 Serverless 解决方案。本文将手把手带你从零搭建一条“上传→触发→处理→存储”的全自动文件处理流水线,无需管理任何服务器,按调用次数付费,且具备毫秒级弹性伸缩能力。
整体架构设计
我们设计的流水线包含三个核心环节:
-
文件上传入口:客户端通过 RESTful API 上传文件,API 网关接收请求并触发函数。
-
业务处理函数:FunctionGraph 函数接收文件内容,执行自定义处理逻辑(例如:图片压缩、格式转换、添加水印、提取元数据等)。
-
结果持久化:处理完成后,将结果文件保存至华为云 OBS(对象存储服务),并将处理记录写入数据库(可选)。
整个流程采用“同步触发 + 异步回调”模式:API 网关同步返回上传结果,而耗时处理可转为异步任务,避免客户端长时间等待。实际部署时,可根据文件大小和业务需求选择同步或异步方式。
第一步:创建 OBS 存储桶
在开始编写函数前,我们需要一个存放原始文件和结果文件的“仓库”。
-
登录华为云控制台,进入对象存储服务 OBS。
-
创建一个新的标准存储桶,例如命名为
file-process-bucket。 -
在该桶下建立两个文件夹:
/raw用于存放原始上传文件,/output用于存放处理后的结果文件。
注意:记录下存储桶的区域(Endpoint)和访问密钥(AK/SK),后续函数中会用到。建议使用 IAM 委托(委托授权)的方式,避免在函数代码中硬编码密钥,提高安全性。
第二步:编写 FunctionGraph 函数
接下来,我们创建一个 Python 3.9 运行时的函数,实现图片压缩和格式转换功能(你也可以换成 PDF 转文本、视频截图等任意逻辑)。
函数核心代码示例:
# -*- coding: utf-8 -*- import json import base64 from PIL import Image import io import boto3 # 兼容 OBS 的 S3 SDK(华为云推荐使用 obs-client,此处为示意) def handler(event, context): """ 函数入口:接收 API 网关传来的文件数据 """ # 1. 解析请求体(API 网关将文件 base64 编码后传入) body = event.get('body', '') if not body: return {"statusCode": 400, "body": "文件内容为空"} # 2. 解码文件内容 file_data = base64.b64decode(body) # 获取文件名(可从请求头或参数中获取) filename = event.get('queryStringParameters', {}).get('filename', 'default.jpg') # 3. 图片处理:压缩至宽度 800px,格式转为 JPEG try: img = Image.open(io.BytesIO(file_data)) img.thumbnail((800, 800)) output_buffer = io.BytesIO() img.save(output_buffer, format='JPEG', quality=85) processed_data = output_buffer.getvalue() except Exception as e: return {"statusCode": 500, "body": f"处理失败: {str(e)}"} # 4. 上传结果到 OBS(使用委托方式获取临时凭证) obs_client = boto3.client('s3', endpoint_url='https://obs.cn-north-4.myhuaweicloud.com', region_name='cn-north-4') result_key = f"output/{filename.split('.')[0]}_compressed.jpg" obs_client.put_object(Bucket='file-process-bucket', Key=result_key, Body=processed_data) # 5. 返回处理结果信息 return { "statusCode": 200, "body": json.dumps({ "message": "处理成功", "output_path": f"obs://file-process-bucket/{result_key}" }) }
说明:上述代码示例依赖 PIL 库,在实际部署时,你需要为 FunctionGraph 函数配置依赖包(可通过 OBS 上传依赖 zip 包或使用函数层 Layer 加载)。为简化演示,这里逻辑清晰展示流程,实际应用请根据自身需求调整。
第三步:配置 API 网关触发器
函数编写完成后,我们需要为其绑定一个 API 网关触发器,让外部请求能直接调用函数。
-
在 FunctionGraph 控制台找到已创建的函数,进入“触发器”选项卡。
-
选择“创建触发器”,类型为“API 网关 APIG”。
-
选择“共享版”或“专享版”(根据你的业务量选择,共享版足够测试)。
-
设置 API 路径,例如
/file/upload,请求方法选择POST。 -
在“请求协议”中勾选 HTTPS,确保传输安全。
-
高级设置中,可以配置“超时时间”和“重试策略”。对于图片处理,建议超时设为 30 秒。
-
确认后,系统会自动生成一个公网访问的 URL(例如
https://xxxx.apig.cn-north-4.huaweicloud.com/file/upload)。
关键参数传递:
-
客户端调用该 URL 时,需将文件内容以 Base64 编码方式放在 POST 请求的 Body 中,同时可以在 Query 参数中传递文件名等信息。
-
API 网关会自动将 Body 和参数封装成
event对象传递给函数。
第四步:测试与验证
你可以使用 Postman 或 curl 命令进行快速测试:
curl -X POST "https://xxxx.apig.cn-north-4.huaweicloud.com/file/upload?filename=test.png" \ -H "Content-Type: application/json" \ -d '{"file_base64": "iVBORw0KGgo..."}' # 此处替换为真实图片的 base64 数据
观察返回的 JSON 结果,并前往 OBS 的 output 文件夹查看是否生成了压缩后的图片文件。
如果第一次调用失败,请检查:
-
函数是否配置了正确的委托权限(需要 OBS 写入权限)。
-
依赖包是否完整(PIL 库是否已加载)。
-
请求体大小是否超过 API 网关限制(默认 10MB,大文件可配置流式传输)。
进阶优化:异步处理与消息队列
对于较大文件(如 50MB 以上的视频),同步调用容易超时。此时我们可以将架构升级为异步模式:
-
API 网关收到请求后,将文件先存入 OBS
raw目录,然后向 华为云 DMS(分布式消息服务) 或 函数工作流异步调用 发送一条“处理任务”消息。 -
主函数立即返回“已接收,正在处理”的响应,提升用户体验。
-
另一个处理函数订阅消息,从 OBS 读取文件并执行耗时操作,完成后将结果地址存入数据库或通知用户。
这种方式兼顾了响应速度和系统可靠性,适合生产环境。
监控与运维
FunctionGraph 提供了丰富的监控指标,包括调用次数、错误率、平均耗时、内存使用等。你可以在 云监控服务 CES 中配置告警规则,当错误率超过阈值或耗时异常时,及时接收通知。
此外,开启函数日志功能,将日志上报至 云日志服务 LTS,方便后续排查问题和分析调用链路。
成本分析
Serverless 架构按实际执行时间和内存计费,且每月有免费额度。对于日处理量在 1 万次以内的小型业务,月度费用几乎可以忽略不计(远低于购买一台云服务器的成本)。当业务量暴增时,FunctionGraph 会自动扩容,无需人工干预,真正实现“按需付费,弹性伸缩”。
结语
通过上述步骤,我们成功利用华为云 FunctionGraph 和 API 网关搭建了一条轻量级、自动化、高可用的文件处理流水线。整个过程无需关心底层服务器,开发人员只需聚焦业务逻辑,极大提升了交付效率。
Serverless 正在重塑云上应用开发模式,它不仅适用于文件处理,在数据清洗、定时任务、Webhook 回调等场景同样表现出色。希望这篇实战文章能给你带来启发,鼓励你尝试将更多业务迁移到 Serverless 架构上,享受云计算带来的红利。
- 点赞
- 收藏
- 关注作者
评论(0)