引言
在原型阶段,Node.js SaaS 应用可以不使用 API 网关就能运行。它可以暴露 Express 路由,在中间件中验证 JWT,并使用一个小的 Redis 限流器来保护登录端点。但当客户开始直接集成 API、跨区域流量增长,以及定价计划依赖于请求配额时,这种架构就变得脆弱了。
此时,API 网关和速率限制的选型就成了业务基础设施的一部分。合适的方案能够保护源服务器、实施公平使用、区分客户等级、发布面向开发者的 API、跨服务路由流量,并为工程团队提供更清晰的地方来应用认证、缓存、分析和滥用控制。
难点在于,“API 网关”这个说法在不同产品中含义不同。Kong 和 Tyk 是全功能 API 管理平台。Zuplo 是面向开发者的托管网关。AWS API Gateway 则与 AWS 无服务工作负载深度集成。Cloudflare 速率限制在边缘保护 API。Express 中间件和基于 Redis 的库则解决了 Node.js 应用内部一个更狭窄但仍很重要的问题。
本文将从生产级 Node.js SaaS 团队的视角对比这些方案:每种方案擅长什么,什么情况下定价会变得复杂,以及如何判断仅靠中间件够用,还是需要真正的 API 网关。
快速对比表
| 方案 | 最适合 | 部署模式 | 速率限制方式 | 成本特征 | 主要权衡 |
|---|---|---|---|---|---|
| Zuplo | 开发者优先的 SaaS API、API 密钥、客户套餐限制 | 托管网关 | 基于策略,可按 IP、用户 ID、API 密钥或自定义属性限制 | 免费/付费托管计划;发布前请确认 | 比自托管更少的底层控制 |
| Kong Gateway / Konnect | 企业 API 管理、混合云、插件生态 | 根据计划支持托管、混合、专用或自托管 | 基于插件,支持本地、集群和 Redis 策略 | 可能因请求量和计划而异;发布前请确认 | 运维和定价的复杂性 |
| Tyk | 开源与企业级 API 管理 | 自托管或托管选项 | API 级别和密钥级别限制 | 开源入口加付费选项;发布前请确认 | 需要网关运维知识 |
| AWS API Gateway | AWS 无服务器 Node.js API、Lambda 集成、AWS 原生认证 | 全托管 AWS 服务 | 限流、使用计划、API 密钥、WAF 集成(取决于 API 类型) | 按 API 调用和数据传输付费;新账户有免费额度 | 高流量或使用 REST API 时成本可能较高 |
| Cloudflare 速率限制 | 边缘防护、登录/API 滥用防御、控制源站成本 | 边缘/WAF 层 | 基于规则的请求匹配表达式 | 随计划不同;发布前请确认 | 本身不是完整的 SaaS API 管理平台 |
| express-rate-limit | 小型 Express 应用、登录/密码重置端点 | 应用内中间件 | 基本 Express 中间件限制 | 直接成本很低 | 缺乏跨服务和边缘防护 |
| rate-limiter-flexible + Redis | 分布式应用内限制、自定义租户逻辑 | 使用共享存储的应用内库 | 基于 Redis 计数器和自定义逻辑 | 需要 Redis 托管与应用维护 | 正确性、运维和可观测性由你负责 |
API 网关应该为 Node.js SaaS 应用做什么
对 SaaS 产品而言,网关不仅仅是反向代理。它是客户、集成、内部服务和 Node.js 应用之间的流量控制层。一个好的网关策略应回答四个问题。
第一,谁在发起请求? 这可能涉及 API 密钥、OAuth 令牌、JWT、mTLS 或签名 webhook 调用。
第二,该角色允许发送多少流量? 速率限制可基于 IP、用户 ID、组织 ID、API 密钥、订阅计划、端点、区域或自定义桶。
第三,超出限制后会发生什么? 系统应返回标准的 429 响应、清晰的速率限制头信息以及合理的重试行为。
第四,决策应在哪里执行? 某些限制适合在边缘执行,而其他限制需要应用状态,应更靠近 Node.js 服务。
一个常见错误是将所有规则都置于 Express 中间件内。这在应用较小时还能工作,但会让滥用流量到达运行时、数据库连接池和日志管道后才被拒绝。另一个错误是在产品 API 包装尚未稳定之前,就把所有规则移至网关,这可能在只要求保护登录路由时引入不必要的复杂性。
实际做法通常是分层:使用边缘或网关限制进行滥用防护和总体流量上限;使用应用层限制执行需要 SaaS 套餐上下文感知的租户业务规则。
面向开发者的托管网关
Zuplo
Zuplo 是中小型 Node.js SaaS 团队较为相关的托管选项之一,因为它围绕开发者工作流构建,而非重型企业网关运维。它的速率限制策略可基于 IP 地址、用户 ID、API 密钥或自定义属性限制请求。Zuplo 的文档还描述了客户套餐限制、配额管理以及返回带合适头信息的 429 响应等用例。
因此,当你的 SaaS 向客户暴露 API 并希望有一个托管层来管理 API 密钥、文档、开发者门户工作流和基于套餐的请求控制时,Zuplo 非常适合。如果你的团队不想运维网关集群、基于 Redis 的网关计数器或多区域控制平面,它也比自托管网关更易采用。
Zuplo 的定价页面目前描述了一个真实的免费套餐和一个带有固定月费加透明每请求附加费用的 Builder 计划,但定价可能快速变化,发布前请确认。编辑要点不仅是“Zuplo 更便宜”或“Zuplo 更简单”,更有意义的区别在于 Zuplo 适合那些需要 API 产品特性但不想投入大型 APIM 平台的团队。
选择面向开发者的托管网关的情况:当你需要 API 密钥、面向客户的 API 文档、使用分析、基于套餐的限制和快速迭代时。避免使用的情况:如果你的公司已经统一使用 Kubernetes Ingress、服务网格或企业级网关平台。
企业级与自托管网关
Kong Gateway
Kong Gateway 是需要成熟插件生态、混合部署模型和企业 API 管理的团队最知名的选项之一。Kong 的速率限制插件可限制 HTTP 请求的时间范围,如秒、分、时、天、月或年。其文档还描述了本地、集群和 Redis 策略,而高级速率限制插件则增加了多重限制、滑动或固定窗口,以及 Redis Sentinel 或 Redis Cluster 支持。
对于 Node.js SaaS 应用,当 API 网关行为是一个平台关注点而非单个应用关注点时,Kong 有意义。例如有多个后端服务、多种协议、混合云、企业安全要求、集中治理以及能安全管理网关配置的平台团队。
成本方面需要仔细审查。Kong 的定价页面目前区分 Plus 和 Enterprise 计划,提及网关限制、包含的请求量、额外请求成本以及大型组织的自定义定价。准确的数字和套餐应在发布前确认,因为企业网关定价经常变化,且通常取决于请求量、支持、部署模式和附加功能。
Tyk
Tyk 是另一个强大的 API 管理选项,尤其适合希望有开源网关路径的团队。Tyk 文档将速率限制描述为控制客户端 API 消费的方式,包括 API 级别和密钥级别的限制。它适合那些想要开源控制但仍需超越简单 Express 中间件的 API 管理功能的团队。
自托管网关并不自动更便宜。它们将成本从供应商发票转移到运维:部署、升级、Redis 或存储依赖、告警、备份、多区域行为及事件响应。当需要控制、合规、自定义网络或高请求量导致托管请求定价过高时,它们最具吸引力。
云提供商网关与边缘速率限制
AWS API Gateway
AWS API Gateway 是已基于 Lambda、ECS、IAM、CloudWatch 和 AWS 原生网络的 Node.js SaaS 应用的天然选择。AWS 定价指出,对于 HTTP API 和 REST API,按收到的 API 调用数和传出数据量付费,无最低费用或预付费。AWS 还列出了新客户的免费套餐,包括每月 100 万次 REST API 调用、100 万次 HTTP API 调用、100 万条 WebSocket 消息和 75 万分钟连接时长,有效期最长 12 个月。
关键的 AWS 决策是 HTTP API 与 REST API。AWS 文档指出 REST API 支持更多功能,而 HTTP API 设计为功能更精简,因此定价更低。当需要 API 密钥、按客户端限流、请求验证、AWS WAF 集成或私有 API 端点等功能时,REST API 更合适。当需要更简单、成本更低的路径进行通用 Lambda 或 HTTP 后端集成时,HTTP API 更好。
对于 SaaS 团队,当应用已是 AWS 原生且团队希望托管扩展、IAM 集成、Lambda 集成和 CloudWatch 指标时,AWS API Gateway 很适合。当 API 平台需要跨多个云服务商或高请求量使按请求计费成为重大开销项时,吸引力较低。
Cloudflare 速率限制
Cloudflare 速率限制则不同。它本身并不是一个完整的 SaaS API 管理平台,但在边缘层非常有用。Cloudflare 的 WAF 速率限制规则允许你为匹配表达式的请求定义速率限制,并在达到限制时选择操作。文档特别提到保护登录端点免受暴力攻击,以及在时间窗口内限制单个客户端的 API 调用。
对于许多 Node.js SaaS 应用而言,Cloudflare 应作为滥用和成本控制层置于一切之前。它能在恶意流量到达 Node.js 运行时、负载均衡器、无服务器函数或托管网关之前进行拦截。但你仍然可能需要网关或应用内限流器来实施客户套餐配额。
应用层 Node.js 速率限制
应用层速率限制仍然有用。问题不在于它是否是“真正的”速率限制,而在于它应该负责什么。
express-rate-limit
express-rate-limit 是 Express 的一个基础速率限制中间件。其文档描述了限制对公共 API 或端点(如密码重置)的重复请求。这使其成为小型应用、原型、管理后台以及需要快速防护机制特定端点的合理首层方案。
import rateLimit from 'express-rate-limit';
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 5, // 限制每个IP每窗口最多5次登录尝试
standardHeaders: true,
legacyHeaders: false,
message: 'Too many login attempts, please try again later.',
});
app.use('/auth/login', loginLimiter);
然而,基本的基于内存的中间件对于水平扩展的 SaaS 应用是不够的。如果运行多个 Node.js 实例,除非使用共享存储,否则每个实例都有自己本地的计数器。这可能导致限制不一致,并增加滥用控制难度。
rate-limiter-flexible + Redis
rate-limiter-flexible 是一种更高级的模式,因为它可以使用 Redis 实现分布式计数器。其 GitHub 示例展示了一个 Redis 限流器,按 IP 消耗点数,并在超出限制时返回 429,并注明它适用于分布式环境,因为限制存储在 Redis 中。
import { RateLimiterRedis } from 'rate-limiter-flexible';
import Redis from 'ioredis';
const redisClient = new Redis({ host: 'localhost', port: 6379 });
const rateLimiter = new RateLimiterRedis({
storeClient: redisClient,
keyPrefix: 'rl',
points: 100, // 100次请求
duration: 60, // 每60秒
});
async function rateLimitMiddleware(req, res, next) {
try {
const tenantId = req.headers['x-tenant-id'] as string;
await rateLimiter.consume(tenantId || req.ip, 1);
next();
} catch {
res.status(429).json({
error: 'Too Many Requests',
retryAfter: Math.ceil(Date.now() / 1000) + 60,
});
}
}
对于 SaaS 产品,当规则需要产品上下文时,基于 Redis 的应用限制特别有用:组织 ID、计划 ID、API 密钥所有者、试用状态、端点组、计费状态或 AI 使用预算。这些规则在应用代码中可能比在网关策略中更容易表达。
缺点在于需要自主管理。你必须实现头信息、重试、日志、仪表盘、绕过策略、测试和故障行为。还需决定 Redis 宕机时发生什么。**故障开放(fail-open)**可保护可用性,但可能允许滥用。**故障关闭(fail-closed)**可保护成本,但可能中断合法客户。
基于团队规模与 API 商业模式的决策框架
独立创始人或小型 SaaS 团队
从最简单的安全设置开始:Cloudflare 或托管服务商的边缘防护,加上针对敏感端点的 express-rate-limit 或基于 Redis 的 rate-limiter-flexible。这足以应对登录、密码重置、邀请端点、公开表单及早期 API 路由。
面向客户的 API、带 API 密钥与付费套餐的 SaaS 应用
考虑托管网关,如 Zuplo。你需要按客户、套餐、路由和令牌的限制,并需要后端代码之外可读的分析。这也是开发者体验变得重要的转折点:文档、示例、密钥轮换以及清晰的 429 行为会影响客户成功。
AWS 原生无服务器产品
仔细评估 AWS API Gateway。当功能集足够时使用 HTTP API,当需要高级功能时使用 REST API。在规模上,成本差异可能很大,因此不要无理由默认选择 REST API。
平台团队或企业级 SaaS 公司
评估 Kong 或 Tyk。当 API 管理跨多个服务和团队共享时,这些工具更强。当你需要混合部署、自托管、插件扩展、治理和集中策略管理时,它们也更合适。
高流量公共 API
承诺前先计算成本模型。托管按请求计费、分析数据保留、开发者门户附加功能、Redis 托管、数据传输、WAF 规则、支持等级和工程运维都可能改变结果。
成本因素与隐性权衡
可见的月度计划价格很少是 API 网关的全部成本。你需要至少对七类成本建模:
- 请求量。 有些平台按请求收费,有些包含请求额度,有些则对你自己运维的基础设施收费。
- 分析与日志保留。 API 分析很有价值,但高基数 API 日志可能会变得昂贵。
- 开发者门户与 API 产品包装。 如果你计划销售 API 访问权限,门户功能可能值得付费。
- 多区域行为。 单区域限流器比全局一致性限流器更简单。
- 状态依赖。 基于 Redis 的限制需要 Redis 可用性及清晰的故障行为。
- 支持与合规。 企业单点登录、审计日志、基于角色的访问控制、私有网络等合规需求,可能推动团队选择更高阶的套餐。
- 团队时间。 自托管网关可能降低供应商支出,但会增加运维负担。
不要仅基于最低起步价选择 API 网关。应根据流量应在何处被拦截、限制如何映射到 SaaS 业务模式,以及事故期间谁将负责系统来做出选择。
推荐的组合模式
早期 Node.js SaaS
对登录和公共端点使用 Cloudflare 速率限制,对简单 Express 保护使用 express-rate-limit,一旦增加了多个应用实例,就迁移到基于 Redis 的 rate-limiter-flexible。这种模式成本低且易于理解。
面向 API 且有付费套餐的 SaaS
使用托管网关管理 API 密钥、文档、用量分析和基于套餐的限制。保留基于 Redis 的应用内限流器处理需要计费或租户上下文的规则。这样既能获得干净的公共 API 层,又不失应用特有的控制。
AWS 原生无服务器 SaaS
使用 AWS API Gateway 配合 Lambda 或 AWS 服务集成。当 HTTP API 够用时优先使用。仅当所需功能集证明更复杂和潜在成本合理时使用 REST API。当公共滥用防护是主要关注点时,在前面加 AWS WAF 或 Cloudflare。
企业或多服务 SaaS 平台
使用 Kong 或 Tyk 作为网关平台,通过 CI/CD 或平台工具管理策略。仅当网关无法安全表达所需业务规则时,才在应用代码中保留服务特定的限制。
结论
对于 Node.js SaaS 应用,API 网关和速率限制的选择应遵循产品成熟度。在 API 商业模式明确之前,不要过度构建企业网关。一旦客户、集成和滥用流量可能影响生产可靠性,就不要仅依赖 Express 中间件。
一条实用路径是:从边缘防护和应用级限制开始,水平扩展时加入 Redis,在面向客户的 API 成为产品一部分时采用面向开发者的托管网关,在 API 管理成为平台职责时迁移到 Kong、Tyk 或云原生网关。
最佳方案是在合适的层次执行合适的限制:边缘层用于滥用防护,网关用于 API 产品,Node.js 应用代码用于租户感知的业务规则。