Serverless 应用开发:AWS Lambda 与 API Gateway

FreeGuideOnline 最新 2026-06-12

什么是 Serverless 无服务器架构?

Serverless 并不是真的“没有服务器”,而是将服务器管理、容量规划和维护工作全部交给云服务商,开发者只需关注业务代码。它的核心思想是事件驱动、按需执行、自动扩缩容、按实际用量付费。AWS Lambda 是最早也最成熟的函数即服务(FaaS)产品,配合 API Gateway 可以快速构建弹性伸缩的云原生 API。

在本教程中,你将亲手创建一个基于 AWS Lambda 和 API Gateway 的无服务器后端,实现一个简单的留言板接口,并了解从开发到监控的完整流程。

前置准备

在开始之前,请确认你具备以下条件:

  • 一个 AWS 账号(注册时需要信用卡,本示例使用的资源都在免费套餐范围内)
  • 本地安装 AWS CLI 并完成 aws configure 配置
  • Node.js 16+ 运行环境
  • 基础的 JavaScript 与 HTTP 协议知识

核心概念速览

  • AWS Lambda 函数
    一段在托管环境中运行的代码,可以由 HTTP 请求、S3 事件、定时触发器等事件源调用。每次执行称为一次“调用”,按调用次数与运行时长计费。

  • API Gateway
    完全托管的 API 管理服务,用于创建、发布、维护 RESTful API。它能将 HTTP 请求代理到 Lambda 函数,并处理身份验证、流量控制、请求/响应转换。

  • 事件驱动模型
    不同于传统持续运行的服务器,Serverless 函数处于休眠状态直到事件到达,然后快速启动执行,执行完毕后释放资源。

实战项目:构建 Serverless 留言板 API

我们将创建一个留言板 API,提供 GET /messagesPOST /messages 两个端点。消息暂时存储在内存数组中(仅为演示,生产环境应使用 DynamoDB 或 RDS)。

第一步:编写 Lambda 函数代码

在本地新建项目文件夹 serverless-message-api,初始化并创建文件。

mkdir serverless-message-api && cd serverless-message-api
npm init -y

创建 index.js(AWS Lambda 的入口文件):

// 简单内存存储,重启 Lambda 后消息会丢失
let messages = [
  { id: 1, text: 'Hello Serverless!', createdAt: new Date().toISOString() }
];

exports.handler = async (event) => {
  // API Gateway 会通过 event.httpMethod 传递 HTTP 方法
  const { httpMethod, path, body } = event;

  // GET /messages 返回消息列表
  if (httpMethod === 'GET' && path === '/messages') {
    return {
      statusCode: 200,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(messages)
    };
  }

  // POST /messages 添加新消息
  if (httpMethod === 'POST' && path === '/messages') {
    try {
      const { text } = JSON.parse(body || '{}');
      if (!text) {
        return {
          statusCode: 400,
          body: JSON.stringify({ error: 'text is required' })
        };
      }
      const newMessage = {
        id: messages.length + 1,
        text,
        createdAt: new Date().toISOString()
      };
      messages.push(newMessage);
      return {
        statusCode: 201,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(newMessage)
      };
    } catch (err) {
      return {
        statusCode: 400,
        body: JSON.stringify({ error: 'Invalid JSON body' })
      };
    }
  }

  // 未匹配的路由
  return {
    statusCode: 404,
    body: JSON.stringify({ error: 'Not Found' })
  };
};

打包函数代码为 ZIP 文件(后续部署需要):

zip -r function.zip index.js

第二步:在 AWS Lambda 控制台创建函数

  1. 登录 AWS 管理控制台,进入 Lambda 服务。
  2. 点击 创建函数,选择 从头开始撰写
  3. 函数名称输入 MessageApiHandler,运行时选择 Node.js 18.x(兼容 16+)。
  4. 架构选择 x86_64,权限部分选择 创建一个具有基本 Lambda 权限的执行角色,AWS 会自动生成一个基础 IAM 角色。
  5. 点击 创建函数

进入函数详情页后,上传代码包:

  • 在“代码源”区域,点击 从 .zip 文件上传,选择刚才生成的 function.zip
  • 上传成功后,编辑器会显示 index.js 内容,可以在这里直接微调。

现在你可以先测试 Lambda 本身:点击 测试,创建一个新的测试事件,模拟 API Gateway 传入的结构。例如:

{
  "httpMethod": "GET",
  "path": "/messages",
  "body": null
}

点击测试,应该能看到返回状态码 200 和消息数组。这一步确保函数逻辑正确。

第三步:配置 API Gateway 触发器

让 Lambda 能够被外部 HTTP 请求调用,需要添加 API Gateway 触发器。

  1. 在 Lambda 函数页面顶部,点击 添加触发器
  2. 触发器源选择 API Gateway
  3. 意图选择 创建新 API,API 类型选择 REST API
  4. 安全选择 打开(本教程为简单演示,生产环境应使用授权或 API 密钥)。
  5. 点击 添加,AWS 会自动创建 API Gateway 资源、方法和集成。

触发器创建完成后,“配置”选项卡会显示 API 端点 URL,类似: https://abcdefghij.execute-api.us-east-1.amazonaws.com/default/MessageApiHandler

此时直接访问这个 URL,你会发现只响应根路径 / 的请求。我们还需要在实际的 API Gateway 控制台进行路由细化,让 Lambda 能感知到不同路径和方法。

第四步:细化 API Gateway 路由设置

  1. 在 Lambda 触发器列表中,点击刚才创建的 API 名称,进入 API Gateway 控制台。
  2. 左侧面板选择 资源,你会看到现有资源结构:/ 下面包含一个 ANY 方法。我们需要创建 /messages 资源,并将 GET 和 POST 方法集成到同一个 Lambda。
  3. 选中 / 根资源,点击 创建资源,资源名称 messages,勾选 启用 API Gateway CORS(方便浏览器调用)。点击 创建资源
  4. 选中 /messages 资源,点击 创建方法,方法类型选 GET,集成类型选择 Lambda 函数,勾选 使用 Lambda 代理集成,Lambda 区域选择与函数一致的区域,函数名输入 MessageApiHandler。点击 创建方法
  5. 同样操作,为 /messages 创建 POST 方法,也使用相同的 Lambda 代理集成。
  6. 现在你可能还需要处理根路径的 ANY 方法,可以删除它或者保留,建议删除以免混淆。

为了让 Lambda 正确解析路径,需要调整代理传递行为。因为使用了 Lambda 代理集成,API Gateway 会把完整的请求信息(包括 pathhttpMethod)传给 Lambda,所以我们的函数内路由逻辑可以正常工作。

第五步:部署 API

在 API Gateway 控制台,点击 部署 API,部署阶段选择 default(如果没有,新建一个 prod 阶段)。部署后你会得到一个调用 URL: https://abcdefghij.execute-api.us-east-1.amazonaws.com/prod

现在的完整端点变成了:

  • GET https://abcdefghij.execute-api.us-east-1.amazonaws.com/prod/messages
  • POST https://abcdefghij.execute-api.us-east-1.amazonaws.com/prod/messages

第六步:测试 API

使用 curl 或 Postman 进行测试:

# 获取消息列表
curl https://your-api-id.execute-api.region.amazonaws.com/prod/messages

# 发送新消息
curl -X POST https://your-api-id.execute-api.region.amazonaws.com/prod/messages \
  -H "Content-Type: application/json" \
  -d '{"text": "Serverless 好方便!"}'

# 再次获取消息,应该看到两条记录
curl https://your-api-id.execute-api.region.amazonaws.com/prod/messages

响应示例:

[
  { "id": 1, "text": "Hello Serverless!", "createdAt": "..." },
  { "id": 2, "text": "Serverless 好方便!", "createdAt": "..." }
]

第七步:监控与日志

每次 Lambda 执行都会自动记录日志到 Amazon CloudWatch Logs。

  1. 在 Lambda 函数控制台,点击 监控 选项卡,可以看到调用次数、错误数、持续时间等指标。
  2. 点击 查看 CloudWatch 日志,可以进入日志组,查看每次请求的详细日志。如果集成出现问题,这里的日志是最重要的排错依据。

你可以在 Lambda 代码中添加 console.log 来输出调试信息,它们会出现在 CloudWatch Logs 中。

进阶优化与实践建议

使用环境变量

不要把数据库连接串或密钥硬编码。在 Lambda 配置页面的 环境变量 中可以添加键值对,代码内通过 process.env.KEY_NAME 访问。

持久化存储

本示例使用内存数组,函数冷启动后数据会丢失。实际项目中,消息应保存到 Amazon DynamoDB(无服务器数据库)或 RDS。Lambda 有与 DynamoDB 的原生集成,可以通过 SDK 直接操作。

冷启动优化

Lambda 在闲置后会被回收,再次唤醒时有冷启动延迟。减少冷启动影响的方法:

  • 使用较小的部署包(< 50 MB)。
  • 选择 nodejs 运行时初始化较快的语言。
  • 避免在全局作用域执行耗时操作(如网络请求),放到 handler 内部。
  • 对于延迟敏感的应用,可配置 预置并发(Provisioned Concurrency,额外付费)。

错误处理与重试

Lambda 默认会重试异步调用(如 S3 触发),API Gateway 调用的同步请求不会自动重试。你的代码应恰当返回错误状态码,让客户端决定重试策略。可以配置 API Gateway 的 网关响应 自定义错误消息格式。

API 网关的更多能力

  • 自定义域名:在 API Gateway 中设置自定义域名并关联 SSL 证书。
  • 请求验证:为 POST 方法配置模型和验证,阻止无效请求进入 Lambda。
  • 使用阶段变量:在不同部署阶段(dev, prod)使用不同的 Lambda 版本或别名。

清理资源

为避免产生意外费用,测试完成后请删除相关资源:

  • 删除 Lambda 函数。
  • 删除 API Gateway 中的 API(在 API 列表选择删除)。
  • 如果创建了 IAM 角色,可在 IAM 控制台删除对应角色。

总结

本教程从零开始搭建了一个完整的无服务器 API,覆盖了 Lambda 函数编写、API Gateway 集成、路由配置、部署与测试。你学会了 Serverless 架构的基本范式:用函数响应事件,用网关暴露服务,一切托管、按需付费。

这一模式极大降低了 Web 应用和后端服务的构建门槛,特别适合微服务、移动后端、IoT 数据处理等场景。下一步,你可以继续探索如何集成 DynamoDB、使用 SAM 模板进行 IaC 部署,或学习 AWS CDK 以编程方式管理云资源。