从零踩坑到优雅落地:基于华为云 FunctionGraph 与 OBS 的无服务器图片处理实战
【摘要】 在最近的项目重构中,我们遇到了典型的非结构化文件处理瓶颈:用户上传的高清原图体积普遍在 5MB 以上,直接入库不仅拖慢客户端加载速度,还造成了不必要的公网下行流量开销。为了实现“上传即压缩”,我们舍弃了常驻 ECS 轮询方案,改用华为云 OBS(对象存储服务)+ FunctionGraph(函数工作流) 构建轻量级的 Serverless 事件驱动链路。核心架构思路整个链路无需常驻进程,按需...
在最近的项目重构中,我们遇到了典型的非结构化文件处理瓶颈:用户上传的高清原图体积普遍在 5MB 以上,直接入库不仅拖慢客户端加载速度,还造成了不必要的公网下行流量开销。
为了实现“上传即压缩”,我们舍弃了常驻 ECS 轮询方案,改用华为云 OBS(对象存储服务)+ FunctionGraph(函数工作流) 构建轻量级的 Serverless 事件驱动链路。
核心架构思路
整个链路无需常驻进程,按需触发:
-
上传原图:前端将图片直传至 OBS 桶的
raw/目录。 -
事件联动:OBS 产生
ObjectCreated事件,自动投递并触发 FunctionGraph。 -
函数处理:函数拉取图片流,调用无损/有损压缩算法调整尺寸与格式(统一转 WebP),输出至
thumbnail/目录。 -
清理释放:执行完毕后容器实例自动回收,实现“零闲置成本”。
极简处理逻辑示例 (Python 3.9)
在 FunctionGraph 中,通过事件入参即可拿到触发文件的元数据:
Python
import os
from PIL import Image
from obs import ObsClient
def handler(event, context):
# 1. 解析 OBS 触发器传递的事件信息
record = event['Records'][0]['obs']
bucket_name = record['bucket']['name']
object_key = record['object']['key']
# 避免无限触发递归(仅处理 raw/ 目录)
if not object_key.startswith("raw/"):
return {"code": 0, "msg": "Skip non-raw image"}
# 2. 从上下文获取临时 AK/SK,无需硬编码
ak = context.getAccessKey()
sk = context.getSecretKey()
server = context.getUserData('obs_server')
obs_client = ObsClient(access_key_id=ak, secret_access_key=sk, server=server)
# 3. 下载、压缩并回传
download_path = f"/tmp/{os.path.basename(object_key)}"
upload_path = f"/tmp/out_{os.path.basename(object_key)}"
obs_client.getObject(bucket_name, object_key, downloadPath=download_path)
with Image.open(download_path) as img:
img.thumbnail((800, 800))
img.save(upload_path, "WEBP", quality=80)
target_key = object_key.replace("raw/", "thumbnail/").rsplit(".", 1)[0] + ".webp"
obs_client.putFile(bucket_name, target_key, upload_path)
return {"code": 200, "target": target_key}
两条关键避坑经验
-
防范事件递归循环调用:OBS 触发器如果监听的是全桶,函数处理后回写新图片至同一存储桶极易陷入“生成图片 $\to$ 触发新事件 $\to$ 再次生成”的死循环。务必配置前缀过滤(如监听
raw/,写入thumbnail/)。 -
利用委托(Agency)鉴权:不要在代码中硬编码固定 AK/SK。为 FunctionGraph 绑定具备 OBS 操作权限的云服务委托,代码直接通过
context.getAccessKey()动态取临时凭证,既安全又便于权限审计。
总结
切换到 Serverless 架构后,图片处理平均耗时控制在 300ms 以内,资源费用直接从包周期虚机的固定月租转为按请求毫秒计费,成本降低了 70% 以上。对于轻量、脉冲式的任务流,善用云原生组件串联能够显著提升交付效率与系统弹性。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)