跳转至

第10章 Serverless架构

Serverless架构图

📚 章节概述

本章将深入讲解Serverless架构,包括AWS Lambda、Cloud Functions等无服务器计算平台的使用。通过本章学习,你将能够设计和实现Serverless应用,实现按需计费和自动扩缩容。

🎯 学习目标

完成本章后,你将能够:

  1. 理解Serverless架构的核心概念
  2. 掌握AWS Lambda的使用
  3. 了解Cloud Functions的使用
  4. 掌握Serverless最佳实践
  5. 能够搭建生产级的Serverless应用

10.1 Serverless概述

10.1.1 什么是Serverless

Serverless是一种云计算执行模型,云服务商动态分配机器资源。

核心价值

  1. 按需计费
  2. 只为实际使用付费
  3. 降低成本
  4. 资源优化

  5. 自动扩缩容

  6. 无需手动管理
  7. 自动应对流量
  8. 高可用性

  9. 简化运维

  10. 无需管理服务器
  11. 专注业务逻辑
  12. 快速迭代

10.1.2 Serverless架构

Text Only
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  API Gateway│    │  Event Bus  │    │  Storage    │
└──────┬──────┘    └──────┬──────┘    └──────┬──────┘
       │                   │                   │
       └───────────────────┼───────────────────┘
                   ┌───────▼────────┐
                   │  Functions    │
                   │  (Lambda/     │
                   │   Cloud Func) │
                   └───────┬────────┘
                   ┌───────▼────────┐
                   │  Services     │
                   │  (Database/   │
                   │   Cache)      │
                   └───────────────┘

10.2 AWS Lambda

10.2.1 Lambda概述

AWS Lambda是AWS的无服务器计算服务。

核心特性

  1. 事件驱动
  2. 支持多种触发器
  3. 实时响应
  4. 灵活集成

  5. 自动扩缩容

  6. 并发执行
  7. 无需配置
  8. 高性能

  9. 多语言支持

  10. Python、Node.js、Java
  11. Go、Ruby、.NET
  12. 自定义运行时

10.2.2 Lambda函数示例

Python函数

Python
import json
import boto3                   # AWS SDK,用于访问AWS服务
from datetime import datetime

def lambda_handler(event, context):
    """Lambda函数处理程序
    event: API Gateway传入的事件对象,包含HTTP请求信息
    context: Lambda运行时上下文(函数名、内存限制、剩余时间等)
    """

    # 从API Gateway v2的事件格式中提取HTTP方法和路径
    http_method = event['requestContext']['http']['method']
    path = event['requestContext']['http']['path']

    # 根据HTTP方法和路径分发请求(简易路由)
    if http_method == 'GET' and path == '/users':
        return get_users()
    elif http_method == 'POST' and path == '/users':
        return create_user(event)
    else:
        return {
            'statusCode': 404,
            'body': json.dumps({'error': 'Not found'})  # json.dumps将Python对象转为JSON字符串
        }

def get_users():
    """获取用户列表"""
    # 初始化DynamoDB资源(建议在函数外初始化以复用连接,减少冷启动开销)
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Users')  # 指定DynamoDB表名

    # scan扫描全表(数据量大时应使用query+分页)
    response = table.scan()
    users = response.get('Items', [])

    # 返回符合API Gateway格式的响应
    return {
        'statusCode': 200,
        'body': json.dumps(users, default=str)  # default=str处理Decimal等类型
    }

def create_user(event):
    """创建用户"""
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Users')

    # 解析请求体中的JSON数据
    body = json.loads(event['body'])  # json.loads将JSON字符串转为Python对象
    user = {
        'userId': body['userId'],      # 用户唯一标识(分区键)
        'name': body['name'],
        'email': body['email'],
        'createdAt': datetime.now().isoformat()  # ISO格式时间戳
    }

    # 写入DynamoDB(put_item为覆盖写入)
    table.put_item(Item=user)

    return {
        'statusCode': 201,             # 201 Created
        'body': json.dumps(user, default=str)
    }

Node.js函数

JavaScript
// AWS SDK v3(v2 已于 2025年9月终止支持)
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');        // DynamoDB底层客户端
const { DynamoDBDocumentClient, ScanCommand, PutCommand } = require('@aws-sdk/lib-dynamodb');  // 文档客户端(自动序列化/反序列化)
// 在函数外初始化客户端,可在多次调用间复用连接(减少冷启动开销)
const client = new DynamoDBClient({});  // const不可重新赋值;let块级作用域变量
const dynamodb = DynamoDBDocumentClient.from(client);

// Lambda入口函数:处理API Gateway事件
exports.handler = async (event) => {  // async定义异步函数;await等待Promise完成
  const httpMethod = event.requestContext.http.method;  // HTTP请求方法
  const path = event.requestContext.http.path;          // 请求路径

  try {  // try/catch捕获异常
    // 路由分发
    if (httpMethod === 'GET' && path === '/users') {
      return await getUsers();  // await等待异步操作完成
    } else if (httpMethod === 'POST' && path === '/users') {
      return await createUser(event);
    } else {
      return {
        statusCode: 404,
        body: JSON.stringify({ error: 'Not found' })
      };
    }
  } catch (error) {
    // 统一错误处理,返回500状态码
    return {
      statusCode: 500,
      body: JSON.stringify({ error: error.message })
    };
  }
};

// 查询所有用户
async function getUsers() {
  const params = {
    TableName: 'Users'                    // DynamoDB表名
  };

  // ScanCommand扫描全表(大数据量场景建议使用QueryCommand + 分页)
  const result = await dynamodb.send(new ScanCommand(params));

  return {
    statusCode: 200,
    body: JSON.stringify(result.Items)    // 返回JSON格式的用户列表
  };
}

// 创建新用户
async function createUser(event) {
  const body = JSON.parse(event.body);    // 解析请求体
  const user = {
    userId: body.userId,                  // 分区键
    name: body.name,
    email: body.email,
    createdAt: new Date().toISOString()   // 创建时间戳
  };

  const params = {
    TableName: 'Users',
    Item: user                            // 要写入的用户数据
  };

  await dynamodb.send(new PutCommand(params));  // 写入DynamoDB

  return {
    statusCode: 201,                      // 201 Created
    body: JSON.stringify(user)
  };
}

10.3 Cloud Functions

10.3.1 Cloud Functions概述

Google Cloud Functions是GCP的无服务器计算服务。

核心特性

  1. 事件驱动
  2. 支持多种触发器
  3. 实时响应
  4. 灵活集成

  5. 自动扩缩容

  6. 并发执行
  7. 无需配置
  8. 高性能

  9. 多语言支持

  10. Python、Node.js、Go
  11. Java、.NET
  12. 自定义运行时

10.3.2 Cloud Functions示例

Python函数

Python
import functions_framework       # Google Cloud Functions框架
from markupsafe import escape    # HTML转义,防止XSS攻击
import json

@functions_framework.http        # HTTP触发器装饰器
def hello_http(request):
    """HTTP Cloud Function
    request: Flask的Request对象,包含HTTP请求的所有信息
    """

    # 尝试从JSON请求体获取参数
    request_json = request.get_json(silent=True)  # silent=True避免解析失败抛异常
    request_args = request.args   # URL查询参数

    # 参数优先级:JSON请求体 > URL查询参数 > 默认值
    if request_json and 'name' in request_json:
        name = request_json['name']
    elif request_args and 'name' in request_args:
        name = request_args['name']
    else:
        name = 'World'

    return f'Hello {escape(name)}!'  # escape防止XSS注入

@functions_framework.cloud_event  # CloudEvent触发器装饰器(事件驱动)
def hello_gcs(event):
    """Cloud Storage Cloud Function
    当GCS存储桶中有文件上传时自动触发
    """

    data = event.data              # CloudEvent事件数据
    bucket_name = data['bucket']   # 触发事件的存储桶名称
    file_name = data['name']       # 上传的文件名

    print(f'File {file_name} uploaded to {bucket_name}')

    return 'OK'

10.4 Serverless最佳实践

10.4.1 函数设计

  1. 无状态
  2. 避免使用本地状态
  3. 使用外部存储
  4. 幂等性设计

  5. 短生命周期

  6. 快速执行
  7. 避免长连接
  8. 异步处理

  9. 错误处理

  10. 完善的错误处理
  11. 重试机制
  12. 死信队列

10.4.2 性能优化

  1. 冷启动优化
  2. 预热函数
  3. 使用连接池
  4. 优化依赖

  5. 内存优化

  6. 合理设置内存
  7. 监控使用情况
  8. 成本优化

  9. 并发控制

  10. 设置并发限制
  11. 使用预留并发
  12. 避免限流

10.5 练习题

基础题

  1. 选择题
  2. Serverless的主要优势是什么?

    • A. 固定成本
    • B. 按需计费
    • C. 需要管理服务器
    • D. 长连接
  3. 简答题

  4. 解释Serverless架构的特点。
  5. 说明Lambda的核心特性。

进阶题

  1. 实践题
  2. 创建一个AWS Lambda函数。
  3. 配置API Gateway触发器。
  4. 实现Serverless应用。

  5. 设计题

  6. 设计一个生产级的Serverless架构。
  7. 设计一个Serverless数据处理流程。

答案

1. 选择题答案

  1. B(Serverless的主要优势是按需计费)

2. 简答题答案

Serverless架构的特点: - 按需计费 - 自动扩缩容 - 简化运维

Lambda的核心特性: - 事件驱动 - 自动扩缩容 - 多语言支持

3. 实践题答案

参见10.2-10.3节的示例。

4. 设计题答案

参见10.1-10.4节的架构设计。

10.6 面试准备

大厂面试题

字节跳动

  1. 解释Serverless架构的优缺点。
  2. Lambda的冷启动是什么?
  3. 如何优化Lambda性能?
  4. 如何设计Serverless应用?

腾讯

  1. Cloud Functions的使用场景是什么?
  2. 如何处理Serverless的错误?
  3. 如何监控Serverless应用?
  4. 如何设计Serverless的容错?

阿里云

  1. Serverless的最佳实践是什么?
  2. 如何实现Serverless的认证?
  3. 如何设计Serverless的成本优化?
  4. 如何处理Serverless的限流?

📚 参考资料

🎯 本章小结

本章深入讲解了Serverless架构,包括:

  1. Serverless的核心概念和架构
  2. AWS Lambda的使用
  3. Cloud Functions的使用
  4. Serverless最佳实践
  5. 完整的实战案例

通过本章学习,你掌握了Serverless的核心技术,能够搭建生产级的Serverless应用。下一章将深入学习云安全最佳实践。