Serverless 架构实战:告别运维烦恼,用云函数构建高并发应用(附完整代码)


阿里云推广

Serverless 架构实战:告别运维烦恼,用云函数构建高并发应用(附完整代码)

你有没有遇到过这样的困境:服务器一闲置就浪费钱,流量一上来就崩?Serverless 可能正是你需要的答案。


什么是 Serverless?先搞清楚概念

很多人听到「Serverless」以为是”没有服务器”,其实不对——准确说法是你不需要管服务器

底层依然有服务器在运行,只不过那是云厂商的事,你只需要写业务代码,按实际调用次数和计算时长付费。

核心特点:

特性 传统服务器 Serverless
—— ———– ————
计费方式 按时间(包月/包年) 按调用次数+时长
运维成本 需要维护操作系统、环境 零运维
扩容方式 手动或半自动 自动弹性扩缩容
冷启动 有(首次调用有延迟)
适用场景 长期稳定型业务 事件驱动、波峰业务

Serverless 的三大核心产品形态

1. 函数计算(FaaS)

这是 Serverless 最核心的形态。你写一个函数,部署上去,触发时自动执行。

主流平台:

  • **腾讯云云函数(SCF)**
  • **阿里云函数计算(FC)**
  • **AWS Lambda**
  • **Azure Functions**
  • 2. 无服务器容器(Serverless Container)

    如果你的应用太复杂,用容器部署但不想管底层资源,可以用:

  • 腾讯云弹性容器实例(ECI)
  • 阿里云 Serverless Kubernetes
  • AWS Fargate
  • 3. BaaS(后端即服务)

    数据库、认证、消息推送等基础设施全托管,如腾讯云开发(CloudBase)、Firebase。


    实战:用腾讯云云函数构建图片压缩服务

    业务场景

    用户上传图片到 COS(对象存储),触发云函数自动压缩,压缩后保存到另一个 Bucket。

    传统做法:需要一台持续运行的服务器监听事件。

    Serverless 做法:只在有图片上传时才运行,每月调用费用可能不到 1 元。

    Step 1:创建 COS Bucket

    # 使用腾讯云 CLI 创建 Bucket
    coscmd config -a YOUR_SECRET_ID -s YOUR_SECRET_KEY -b your-upload-bucket-1234567890 -r ap-guangzhou
    coscmd createbucket

    或者在控制台创建两个 Bucket:

  • `images-upload`:接收原始上传
  • `images-compressed`:存储压缩后的图片
  • Step 2:编写云函数代码

    import json
    import os
    import boto3
    from PIL import Image
    import io
    
    # 云函数入口
    def main_handler(event, context):
        """
        触发器:COS 对象创建事件
        功能:压缩图片并保存到目标 Bucket
        """
        
        # 解析触发事件
        cos_records = event.get('Records', [])
        
        for record in cos_records:
            cos_event = record.get('cos', {})
            bucket_name = cos_event['cosBucket']['name']
            object_key = cos_event['cosObject']['key']
            region = cos_event['cosBucket']['appid']
            
            print(f"处理文件: {object_key}")
            
            # 初始化 COS 客户端(云函数内无需密钥,使用临时凭证)
            import qcloud_cos
            from qcloud_cos import CosConfig, CosS3Client
            
            config = CosConfig(
                Region='ap-guangzhou',
                SecretId=os.environ.get('TENCENTCLOUD_SECRETID'),
                SecretKey=os.environ.get('TENCENTCLOUD_SECRETKEY'),
                Token=os.environ.get('TENCENTCLOUD_SESSIONTOKEN')
            )
            client = CosS3Client(config)
            
            # 下载原始图片
            response = client.get_object(
                Bucket=bucket_name,
                Key=object_key
            )
            image_data = response['Body'].get_raw_stream().read()
            
            # 压缩图片(使用 Pillow)
            img = Image.open(io.BytesIO(image_data))
            
            # 转换为 RGB(处理 PNG 透明通道)
            if img.mode in ('RGBA', 'P'):
                img = img.convert('RGB')
            
            # 调整尺寸(最大宽度 1920px)
            max_width = 1920
            if img.width > max_width:
                ratio = max_width / img.width
                new_height = int(img.height * ratio)
                img = img.resize((max_width, new_height), Image.LANCZOS)
            
            # 压缩输出
            output_buffer = io.BytesIO()
            img.save(output_buffer, format='JPEG', quality=85, optimize=True)
            output_buffer.seek(0)
            
            compressed_size = len(output_buffer.getvalue())
            original_size = len(image_data)
            ratio = (1 - compressed_size / original_size) * 100
            
            print(f"压缩率: {ratio:.1f}% ({original_size} -> {compressed_size} bytes)")
            
            # 上传到目标 Bucket
            target_bucket = 'images-compressed-1234567890'
            client.put_object(
                Bucket=target_bucket,
                Key=object_key,
                Body=output_buffer.getvalue()
            )
            
            print(f"已上传到: {target_bucket}/{object_key}")
        
        return {
            'statusCode': 200,
            'body': json.dumps({'message': '处理完成', 'count': len(cos_records)})
        }

    Step 3:配置依赖

    在函数目录创建 requirements.txt

    Pillow==10.3.0
    cos-python-sdk-v5==1.9.30

    打包上传:

    pip install -r requirements.txt -t ./package
    cd package && zip -r ../function.zip .
    cd .. && zip -g function.zip index.py

    Step 4:配置触发器

    在腾讯云控制台:

    1. 进入云函数 → 新建函数

    2. 运行环境选 Python 3.9

    3. 上传 function.zip

    4. 添加触发器 → 选择 COS → 选择 images-upload Bucket → 事件类型:全部创建事件

    Step 5:设置内存和超时

    图片处理推荐配置:

  • 内存:512MB(大图可调到 1GB)
  • 超时:60 秒
  • 并发:100(根据业务需求调整)

  • Serverless 的适用场景和踩坑总结

    最适合用 Serverless 的场景

    事件驱动型任务:文件上传触发、数据库变更触发、定时任务

    波峰型 API:营销活动接口(平时低流量,活动期间暴增)

    Webhook 处理:接收微信、支付宝、第三方回调

    轻量后端 API:CRUD 接口、数据聚合、微服务单接口

    数据处理管道:日志处理、ETL、消息队列消费

    不适合用 Serverless 的场景

    长连接服务:WebSocket、实时推送(冷启动会断连)

    有状态服务:需要本地磁盘缓存、内存状态的应用

    超长时间任务:单次执行超过 15 分钟(AWS Lambda 上限)

    高频低延迟 API:对 100ms 以内响应有要求的接口

    三大常见踩坑

    坑1:冷启动问题

    首次调用或长时间未调用后,会有 500ms~3s 的冷启动延迟。

    解决方案:

    # 方案1:预置并发(腾讯云SCF支持)
    # 在控制台设置预置并发数 = 10,保持热实例
    
    # 方案2:定时预热,每5分钟触发一次"心跳"请求
    import requests
    def warm_up():
        requests.get('https://your-function-url/ping', timeout=5)

    坑2:依赖包太大

    云函数有部署包大小限制(腾讯云 SCF 解压后最大 500MB)。

    解决方案:

  • 使用 Layer(层)共享依赖,多个函数复用
  • 精简依赖,只安装必要的子模块
  • 坑3:临时文件路径

    云函数只有 /tmp 目录可写,且大小有限制(512MB)。

    # ✅ 正确写法
    import tempfile
    with tempfile.NamedTemporaryFile(dir='/tmp', suffix='.jpg') as f:
        f.write(image_data)
    
    # ❌ 错误写法:尝试写入其他目录会权限拒绝
    with open('/var/data/image.jpg', 'wb') as f:
        f.write(image_data)

    费用估算:Serverless 到底能省多少钱?

    以图片压缩服务为例,假设每天处理 10,000 张图片:

    项目 传统服务器 Serverless
    —— ———– ————
    计算成本 1核2G ECS:约¥50/月 按调用:约¥3/月
    流量成本 包含在 ECS 费用中 单独计费,约¥5/月
    运维成本 需要人工维护 零运维
    总计 ~¥50/月 ~¥8/月

    月省约 ¥42,节省 84%。

    当然,如果你的业务是持续高并发(每分钟几万请求),Serverless 的费用可能反而更高——需要根据实际调用量测算。


    小结

    Serverless 不是银弹,但对于事件驱动、低频调用、波峰业务来说,它是降本提效的利器。

    建议行动路线:

    1. 先从一个非核心的小功能开始实践(如文件处理、Webhook 接收)

    2. 熟悉冷启动、依赖管理等坑点

    3. 逐步迁移适合的业务场景

    不要一上来就把整个应用 Serverless 化——那会踩很多不必要的坑。


    关于作者

    长期关注大模型应用落地与云服务器实战,专注技术在企业场景中的落地实践。

    个人博客:yunduancloud.icu —— 持续更新云计算、AI大模型实战教程,欢迎访问交流。

    发表评论