ServerlessArchitecture serverless-architecture

无服务器架构设计和实现指南,涵盖AWS Lambda、Azure Functions和GCP Cloud Functions等事件驱动模式和编排技术,适用于构建高效、可扩展的云原生应用。

Serverless 0 次安装 0 次浏览 更新于 3/4/2026

无服务器架构

概述

无服务器架构允许在不管理服务器的情况下构建完整的应用程序。使用托管的计算服务、数据库和消息系统设计事件驱动、可扩展的系统。仅按实际使用付费,并自动扩展。

何时使用

  • 事件驱动应用程序
  • API后端和微服务
  • 实时数据处理
  • 批量作业和计划任务
  • 工作流自动化
  • IoT数据管道
  • 多租户SaaS应用程序
  • 移动应用后端

实施示例

1. 无服务器应用程序架构

# serverless.yml - 无服务器框架
service: my-app

frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  stage: ${opt:stage, 'dev'}
  memorySize: 256
  timeout: 30
  environment:
    STAGE: ${self:provider.stage}
    DYNAMODB_TABLE: ${self:service}-users-${self:provider.stage}
    SNS_TOPIC_ARN: arn:aws:sns:${self:provider.region}:${aws:accountId}:my-topic
  httpApi:
    cors: true
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - dynamodb:Query
            - dynamodb:Scan
            - dynamodb:GetItem
            - dynamodb:PutItem
            - dynamodb:UpdateItem
            - dynamodb:DeleteItem
          Resource: "arn:aws:dynamodb:${self:provider.region}:${aws:accountId}:table/${self:provider.environment.DYNAMODB_TABLE}"
        - Effect: Allow
          Action:
            - sns:Publish
          Resource: ${self:provider.environment.SNS_TOPIC_ARN}

functions:
  # HTTP API端点
  getUser:
    handler: src/handlers/getUser.handler
    events:
      - httpApi:
          path: /api/users/{id}
          method: GET

  listUsers:
    handler: src/handlers/listUsers.handler
    events:
      - httpApi:
          path: /api/users
          method: GET

  createUser:
    handler: src/handlers/createUser.handler
    events:
      - httpApi:
          path: /api/users
          method: POST

  # 事件驱动函数
  processUserCreated:
    handler: src/handlers/processUserCreated.handler
    events:
      - sns:
          arn: arn:aws:sns:${self:provider.region}:${aws:accountId}:user-created
          topicName: user-created

  processPendingOrders:
    handler: src/handlers/processPendingOrders.handler
    timeout: 300
    events:
      - schedule:
          rate: cron(0 2 * * ? *)
          enabled: true

  # S3事件处理器
  processImageUpload:
    handler: src/handlers/processImageUpload.handler
    events:
      - s3:
          bucket: my-uploads-${self:provider.stage}
          event: s3:ObjectCreated:*
          rules:
            - prefix: uploads/
            - suffix: .jpg

  # SQS队列处理器
  processQueue:
    handler: src/handlers/processQueue.handler
    events:
      - sqs:
          arn: arn:aws:sqs:${self:provider.region}:${aws:accountId}:my-queue
          batchSize: 10
          batchWindow: 5

resources:
  Resources:
    UsersTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${self:provider.environment.DYNAMODB_TABLE}
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
          - AttributeName: createdAt
            AttributeType: N
        KeySchema:
          - AttributeName: id
            KeyType: HASH
          - AttributeName: createdAt
            KeyType: RANGE
        BillingMode: PAY_PER_REQUEST
        StreamSpecification:
          StreamViewType: NEW_AND_OLD_IMAGES

    UserNotificationTopic:
      Type: AWS::SNS::Topic
      Properties:
        TopicName: user-created-${self:provider.stage}

    ProcessingQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: my-queue-${self:provider.stage}
        VisibilityTimeout: 300
        MessageRetentionPeriod: 1209600

plugins:
  - serverless-python-requirements
  - serverless-plugin-tracing
  - serverless-offline
  - serverless-dynamodb-local

2. 事件驱动Lambda处理器模式

// src/handlers/processUserCreated.js
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();

const userService = require('../services/userService');
const emailService = require('../services/emailService');

exports.handler = async (event, context) => {
  console.log('Processing user created event:', JSON.stringify(event));

  try {
    // 解析SNS消息
    const records = event.Records;

    for (const record of records) {
      const message = JSON.parse(record.Sns.Message);
      const userId = message.userId;

      // 获取用户详情
      const user = await userService.getUser(userId);

      // 发送欢迎电子邮件
      await emailService.sendWelcomeEmail(user);

      // 初始化用户偏好设置
      await dynamodb.put({
        TableName: process.env.DYNAMODB_TABLE,
        Item: {
          id: userId,
          preferences: {
            newsletter: true,
            notifications: true
          },
          createdAt: Date.now()
        }
      }).promise();

      // 日志记录成功
      console.log(`Successfully processed user creation for ${userId}`);
    }

    return {
      statusCode: 200,
      body: JSON.stringify({ message: 'Processed' })
    };
  } catch (error) {
    console.error('Error processing event:', error);
    throw error; // SNS将重试
  }
};

// src/handlers/processImageUpload.js
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const rekognition = new AWS.Rekognition();

exports.handler = async (event, context) => {
  try {
    for (const record of event.Records) {
      const bucket = record.s3.bucket.name;
      const key = record.s3.object.key;

      console.log(`Processing image: s3://${bucket}/${key}`);

      // 使用Rekognition分析图像
      const labels = await rekognition.detectLabels({
        Image: {
          S3Object: {
            Bucket: bucket,
            Name: key
          }
        },
        MaxLabels: 10,
        MinConfidence: 70
      }).promise();

      // 创建缩略图
      await createThumbnail(bucket, key);

      // 索引元数据
      await indexMetadata(bucket, key, labels);

      console.log(`Completed processing ${key}`);
    }
  } catch (error) {
    console.error('Error processing S3 event:', error);
    throw error;
  }
};

async function createThumbnail(bucket, key) {
  // 实现
  return true;
}

async function indexMetadata(bucket, key, labels) {
  // 实现
  return true;
}

3. 使用Step Functions进行编排

{
  "Comment": "订单处理工作流",
  "StartAt": "ValidateOrder",
  "States": {
    "ValidateOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:region:account:function:validateOrder",
      "Next": "CheckInventory",
      "Catch": [
        {
          "ErrorEquals": ["InvalidOrder"],
          "Next": "OrderFailed"
        }
      ]
    },
    "CheckInventory": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:region:account:function:checkInventory",
      "Next": "InventoryDecision"
    },
    "InventoryDecision": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.inStock",
          "BooleanEquals": true,
          "Next": "ProcessPayment"
        }
      ],
      "Default": "OutOfStock"
    },
    "ProcessPayment": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:region:account:function:processPayment",
      "Next": "PaymentDecision",
      "Retry": [
        {
          "ErrorEquals": ["PaymentError"],
          "IntervalSeconds": 2,
          "MaxAttempts": 3,
          "BackoffRate": 2.0
        }
      ]
    },
    "PaymentDecision": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.paymentApproved",
          "BooleanEquals": true,
          "Next": "ShipOrder"
        }
      ],
      "Default": "PaymentFailed"
    },
    "ShipOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:region:account:function:shipOrder",
      "Next": "NotifyCustomer"
    },
    "NotifyCustomer": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "TopicArn": "arn:aws:sns:region:account:order-updates",
        "Message": {
          "orderId.$": "$.orderId",
          "status": "shipped"
        }
      },
      "Next": "OrderSuccess"
    },
    "OrderSuccess": {
      "Type": "Succeed"
    },
    "OutOfStock": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:region:account:function:notifyOutOfStock",
      "Next": "OrderFailed"
    },
    "PaymentFailed": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:region:account:function:handlePaymentFailure",
      "Next": "OrderFailed"
    },
    "OrderFailed": {
      "Type": "Fail",
      "Error": "OrderFailed",
      "Cause": "Order processing failed"
    }
  }
}

4. 监控和可观测性

# 监控助手
import json
import logging
from aws_lambda_powertools import Logger, Tracer, Metrics
from aws_lambda_powertools.utilities.typing import LambdaContext

logger = Logger()
tracer = Tracer()
metrics = Metrics()

@logger.inject_lambda_context
@tracer.capture_lambda_handler
def handler(event: dict, context: LambdaContext) -> dict:
    try:
        logger.info("Processing event", extra={"event": event})

        # 添加自定义指标
        metrics.add_metric(
            name="OrderProcessed",
            unit="Count",
            value=1
        )
        metrics.add_metric(
            name="OrderAmount",
            unit="None",
            value=event.get('amount', 0)
        )

        # 业务逻辑
        result = process_order(event)

        logger.info("Order processed successfully", extra={"orderId": result['orderId']})
        return result

    except Exception as e:
        logger.exception("Error processing order")
        metrics.add_metric(
            name="OrderFailed",
            unit="Count",
            value=1
        )
        raise

    finally:
        metrics.flush()

def process_order(event):
    return {"orderId": event.get("id"), "status": "completed"}

最佳实践

✅ DO

  • 设计幂等函数
  • 有效使用事件源
  • 实施适当的错误处理
  • 使用CloudWatch/Application Insights进行监控
  • 使用基础设施即代码
  • 实施分布式跟踪
  • 版本控制函数以安全部署
  • 使用环境变量进行配置

❌ DON’T

  • 创建长时间运行的函数
  • 在函数中存储状态
  • 忽略冷启动优化
  • 使用同步链
  • 跳过测试
  • 硬编码配置
  • 无监控部署

架构模式

  • 事件源用于审计跟踪
  • CQRS用于读写优化
  • 用于分布式事务的Saga模式
  • 死信队列用于故障处理
  • 扇出/扇入用于并行处理
  • 断路器用于弹性

资源