实战案例 | 使用 Amazon Lambda 自动压缩上传到 S3 的图像


  项目需求

某电商网站需要自动化处理用户上传到 Amazon S3 存储桶上的高清商品图片。要求的指标包括:自动压缩图片至 800 × 800 像素以内,降低存储成本;压缩后的图片需存储至指定S3桶,并保留原始路径结构; 处理延迟需控制在1秒内,支持每日1万张图片处理。

  解决方案

采用 AWS Lambda + S3 架构。
触发机制:通过 S3 的 PUT 事件触发 Lambda 函数。
核心逻辑:使用 Python 的 Pillow 库处理图片,依赖Lambda的临时存储(/tmp 目录)。
性能优化:内存配置为 1024 MB,缩短执行时间至 0.5 秒;压缩包精简至 10 MB,避免冷启动产生延迟。

  作业步骤

本次采用 AWS Console 界面完成作业。
注意:根据项目的具体情况,可以采用不同的实施方法。比如使用命令行(CLI)部署、代码部署 (CloudFomation、Terraform等)、以及其它开发语言(SDK)完成作业。

步骤一:创建 S3 存储桶
在 AWS 控制台创建两个 S3 存储桶,一个用于存储原始图片(如 original-images-bucket),另一个用于存储压缩后的图片(如 compressed-images-bucket)。

步骤二:配置 Lambda 函数
创建 Lambda 函数,选择 Python 运行时。编写代码实现图片压缩逻辑,使用 Pillow 库打开原始图片,调整图片质量和尺寸进行压缩,然后将压缩后的图片上传到 compressed-images-bucket。
代码实现(Python):

  import boto3
  from PIL import Image
  
  def lambda_handler(event, context):
      s3 = boto3.client('s3')
      bucket = event['Records'][0]['s3']['bucket']['name']
      key = event['Records'][0]['s3']['object']['key']
      img = Image.open(s3.get_object(Bucket=bucket, Key=key)['Body'])
      img.thumbnail((800, 800))
      compressed_key = f"compressed/{key.split('/')[-1]}"
      img.save(f"/tmp/{compressed_key}")
      s3.upload_file(f"/tmp/{compressed_key}", bucket, compressed_key)
      return {'statusCode': 200}
  

步骤三:依赖处理:本地安装Pillow并打包至ZIP文件:

pip install pillow -t .
zip -r lambda.zip .

步骤四:部署与配置
在 Lambda 控制台创建函数,上传 ZIP 包;配置S3触发器,指定输入桶和PUT事件;设置内存为 1024 MB,超时时间为 10 秒。

步骤五:监控与优化
启用 CloudWatch Logs 记录执行日志;通过 X-Ray 分析调用链,发现S3调用延迟并优化;设置错误告警(如错误率>5%)。

  结果验证

1. 功能测试
上传测试图片到 original-images-bucket,检查 Lambda 函数是否成功执行,压缩后的图片是否正确存储到 compressed-images-bucket;验证图片尺寸是否符合要求(≤800×800)。

2. 性能测试
模拟 1000 张图片上传,记录平均处理时间为 0.5 秒;成本估算:每日 1 万张图片,月成本约$1(基于 AWS Lambda 免费额度)。

3. 错误验证
上传非图片文件或损坏的图片文件,检查日志是否记录错误详情。

4. 删除资源
验证结束后,删除创建的所有 AWS 资源,以避免产生不必要的费用。