4. API Gateway高级特性

当REST API已经能稳定承载请求后,真正决定一个Serverless API能否上生产的,往往是这些“高级特性”:实时双向通信、域名与证书、限流与配额、缓存、以及可观测性。它们分别解决连接模型、入口可信、成本与稳定性、性能、排障五类问题。本节按“能力—关键配置—观察点”的顺序展开,并给出可直接参考的配置片段。

WebSocket API:把请求-响应升级为长连接

REST API是“客户端发起、服务端响应”的短连接模型;WebSocket API则在客户端与API Gateway之间建立一条持久双向连接。API Gateway为每条连接分配connectionId,后端通过回调地址向指定连接推送消息。路由不再由HTTP方法和路径决定,而由$request.body.action或路由键选择,常用内置路由有$connect、$disconnect、$default。

典型配置:集成类型选AWS_PROXY或HTTP_PROXY,后端用Lambda处理连接生命周期。连接建立时把connectionId写入DynamoDB,断开时删除,推送时按业务键查出connectionId再调用PostToConnection。回调地址形如:

https://{api-id}.execute-api.{region}.amazonaws.com/{stage}
POST /{stage}/@connections/{connectionId}

需要注意:连接有10分钟空闲超时和最长2小时连接时长,需靠心跳(ping/pong)保活;PostToConnection遇到GoneException说明连接已失效,应清理存储中的connectionId。WebSocket适合聊天、协同编辑、实时通知、行情推送等场景,而不是替代普通REST查询。

WebSocket API 连接与消息路由 客户端 wss:// 长连接 API Gateway $connect / $disconnect $default + 自定义路由 Lambda 后端 处理 action 消息 调用 PostToConnection DynamoDB connectionId ↔ 用户 GoneException 时清理 推送回客户端 关键约束 空闲超时 10 分钟 · 最长连接 2 小时 · 需心跳保活 · 失效连接返回 GoneException 并清理

自定义域名与TLS:让入口可信且稳定

默认的execute-api域名不适合对外发布。自定义域名需要三样东西:域名、ACM证书、DNS记录。证书必须在us-east-1(弗吉尼亚北部)申请,因为API Gateway的边缘优化端点只接受该区域的ACM证书;若使用区域端点,则证书需与API同区域。证书状态必须为“已颁发”,且覆盖所用域名(如api.example.com或通配符*.example.com)。

创建自定义域名时选择端点类型:边缘优化适合全球用户,区域端点适合与同区域资源配合、便于自管CDN。随后配置API映射,把api.example.com/v1指向某个API的某个stage,基础路径可留空或设为v1。最后在DNS中为域名添加指向API Gateway目标域名的CNAME或A(Alias)记录。TLS方面,API Gateway强制使用TLS 1.2,并支持安全策略选择;若需双向TLS(mTLS),可在自定义域名上启用信任库,校验客户端证书。

证书与域名不匹配、证书不在us-east-1、DNS未生效,是自定义域名最常见的三类失败原因。排查时先看证书状态与区域,再核对API映射的基础路径,最后用dig或nslookup确认解析。

使用计划、API密钥与配额

使用计划(Usage Plan)把“谁在用”和“能用多少”绑定起来。流程是:创建API密钥 → 创建使用计划并设置节流与配额 → 把API阶段关联到计划 → 把密钥加入计划。节流分两个维度:速率(每秒请求数,稳态)和突发(令牌桶容量,允许短时超出)。配额则按天/周/月限制总请求数,超出后返回429。

示例:为某API设置速率100 req/s、突发200、日配额10000。若某客户端在1秒内发来250个请求,前200个(突发容量)可通过,其余在令牌补充前被拒;若当天累计达到10000,则后续请求全部返回429,直到配额周期重置。API密钥通过x-api-key请求头传递,它用于识别与计量,不是身份认证机制,真正的鉴权仍应使用IAM、Cognito或Lambda授权方。

缓存配置:把重复读挡在入口

阶段级缓存可显著降低后端调用与延迟。开启后需设置缓存容量(如0.5GB、1.6GB、6.1GB等),并按方法覆盖缓存行为:是否启用、TTL(默认300秒,可设0~3600秒)、是否加密。缓存键默认包含路径与方法,可额外加入查询字符串、请求头或Cookie中的字段,但键越细命中率越低。

失效策略有两种:客户端请求头带Cache-Control: max-age=0可绕过缓存;后端响应头带Cache-Control: no-cache可写入但不缓存。对写操作(POST/PUT/DELETE)应关闭缓存,避免脏读。判断缓存是否生效,可观察响应头x-cache:Hit表示命中,Miss表示回源,RefreshHit表示TTL到期后回源刷新。

访问日志与执行日志:两条互补的观测线

访问日志(Access Logging)记录每个请求的结构化信息,写入CloudWatch Logs,字段可自定义,常用$context.requestId、$context.status、$context.responseLatency、$context.integrationLatency、$context.identity.sourceIp。它回答“谁在什么时候调用了什么、结果如何”。执行日志(Execution Logging)记录API Gateway自身的执行过程,级别为OFF、ERROR、INFO,INFO会输出请求与响应体等细节,适合定位映射模板、授权、集成失败等问题,但会产生额外费用且可能记录敏感数据,生产环境建议先用ERROR。

日志类型记录内容典型用途成本与风险
访问日志请求元数据、状态码、延迟流量分析、告警、审计低,字段可控
执行日志执行阶段细节、请求/响应体排障、验证映射与授权较高,可能含敏感数据

实践建议:为访问日志定义固定JSON格式并开启,便于用CloudWatch Logs Insights按status和responseLatency聚合;执行日志仅在排障时临时开到INFO,问题定位后调回ERROR。把requestId同时写入后端日志,就能在两条日志线之间做关联追踪,快速还原一次失败请求的完整路径。