- 文档
- 教程
- 后端
【免费下载链接】nodebestpractices
✅ The Node.js best practices list (July 2026)
导读
本文基于开源仓库 nodebestpractices 的《安全实践》章节(原文档:sections/security/limitrequests.russian.md)整理而成,系统讲解如何在 Node.js 应用中实施请求限流(rate limiting),以抵御 DDoS 攻击、暴力破解与突发流量导致的资源耗尽。读完本文你将掌握两条完整的落地路线:一是基于 Redis 的rate-limiter-flexible纯 Node.js 限流方案,二是面向 Express.js 的express-rate-limit中间件方案,并理解为什么限流任务通常更适合交给 nginx 等专用基础设施来完成。
为什么 Node.js 应用必须实现限流
核心观点:限流必须在你的应用中落地,否则应用很容易在同一时间被过多请求压垮。Node.js 是单线程事件循环模型,CPU 与连接处理能力有限,当并发请求超出承载能力时,轻则响应延迟飙升,重则进程崩溃、服务不可用,真实用户因此获得降级甚至不可用的服务体验——这正是拒绝服务(Denial of Service)攻击的典型后果。
关于这一结论,仓库主文档 README.md 的第 6.2 条给出了同样明确的警示:
- 要点(TL;DR):DoS 攻击非常普遍且实施成本低。应使用外部服务(云负载均衡器、云防火墙、nginx)、
rate-limiter-flexible包,或(对于规模较小、非关键的应用)限流中间件(如express-rate-limit)来实施限流。 - 不这样做的后果(Otherwise):应用可能遭受攻击导致拒绝服务,真实用户获得降级或不可用的服务。
主文档将该实践标记为 OWASP Threats ——DDOS,说明限流是安全纵深防御中直接对应 DDoS 威胁面的关键控制点。这一点在仓库的 通用安全最佳实践 中也有呼应——其 OWASP A6(安全配置错误)清单明确要求"使用 HTTP(S) 和 TCP 负载均衡器防御 DDoS 攻击"。
方案选型:基础设施级限流 vs 应用内限流
原文档明确指出:限流是一个任务,最好交给为此设计的专用服务来执行。两类方案定位不同:
| 方案 | 代表实现 | 适用场景 | 特点 |
|---|---|---|---|
| 基础设施级 | nginx、云负载均衡器、云防火墙 | 生产环境、高流量、需要全局限流 | 在请求到达应用前拦截,性能开销极小,天然分布 |
| 应用内中间件/包 | rate-limiter-flexible、express-rate-limit | 中小应用、按路由/业务定制限流 | 灵活,可按 IP、用户名、路径等维度精细化控制 |
两者的关系不是二选一,而是纵深防御的两层:基础设施先挡掉最粗粒度的洪峰,应用内再针对/login、/api等敏感路由做精细化限制。
代码示例一:纯 Node.js + rate-limiter-flexible + Redis
原文档给出的第一种落地方式是使用 rate-limiter-flexible 包,在不依赖 Express 框架的纯 Node.js HTTP 服务中实现限流:
const http = require('http'); const redis = require('redis'); const { RateLimiterRedis } = require('rate-limiter-flexible'); const redisClient = redis.createClient({ enable_offline_queue: false, }); // Maximum 20 requests per second const rateLimiter = new RateLimiterRedis({ storeClient: redisClient, points: 20, duration: 1, blockDuration: 2, // block for 2 seconds if consumed more than 20 points per second }); http.createServer(async (req, res) => { try { const rateLimiterRes = await rateLimiter.consume(req.socket.remoteAddress); // Some app logic here res.writeHead(200); res.end(); } catch { res.writeHead(429); res.end('Too Many Requests'); } }) .listen(3000);参数与原理逐项拆解
enable_offline_queue: false:禁用 Redis 客户端的离线队列。当 Redis 暂时不可用时,请求不会在本地排队等待,而是立刻失败,从而避免"Redis 挂了应用也跟着挂"的连锁故障。points: 20:时间窗口内允许消费的额度(即允许的请求数)。duration: 1:时间窗口长度为 1 秒。二者组合即"每秒最多 20 个请求"。blockDuration: 2:一旦在 1 秒内消耗超过 20 点,则封禁 2 秒。封禁期间所有来自该 IP 的请求都会被直接拒绝,这是区别于单纯"限速"的"拉黑"机制,能更有效地压制恶意流量。rateLimiter.consume(req.socket.remoteAddress):以客户端 IP 为 key 消费额度。调用成功(返回rateLimiterRes)继续执行业务逻辑;额度耗尽时consume会抛异常,进入catch分支。- 响应码
429 Too Many Requests:HTTP 标准中专门用于"请求过于频繁"的状态码,客户端与上游基础设施都能据此识别限流触发。
原文档英文版(sections/security/limitrequests.md)使用
ioredis客户端(enableOfflineQueue: false),俄文版使用官方redis客户端(enable_offline_queue: false)。两者 API 对应,实际项目按已引入的 Redis 客户端选其一即可,限流器本体RateLimiterRedis的配置完全一致。
分布式语义
由于限流计数器存储在 Redis 中,RateLimiterRedis天然支持多实例共享额度:当应用水平扩展为多个 Node.js 进程/容器时,所有实例写入同一个 Redis,限流阈值在集群层面全局生效,这正是它相比进程内计数方案的核心优势。仓库中更复杂的场景可以参考 登录暴力破解防护——它创建了两个限流器:一个按"用户名 + IP"组合统计连续失败次数(最多 10 次),另一个按 IP 统计每日失败总数(100 次后封禁 1 天),展示了keyPrefix、blockDuration等参数在业务安全场景中的组合用法。
代码示例二:Express.js 中间件为特定路由限流
对于 Express.js 应用,原文档推荐使用 express-rate-limit 中间件,以极少的代码为指定路由挂载限流:
const RateLimit = require('express-rate-limit'); // important if behind a proxy to ensure client IP is passed to req.ip app.enable('trust proxy'); const apiLimiter = new RateLimit({ windowMs: 15*60*1000, // 15 minutes max: 100, }); // only apply to requests that begin with /user/ app.use('/user/', apiLimiter);关键点说明
app.enable('trust proxy')(必须):当应用部署在反向代理(nginx、云负载均衡器)之后时,Express 默认取 socket 直连地址作为req.ip,得到的将是代理的 IP 而非真实客户端 IP,限流会全部误判到代理头上。开启trust proxy后,Express 才会信任代理转发来的X-Forwarded-For头并正确解析客户端 IP。这是反代场景下限流能否生效的前提条件,原文档特别标注了这一点。windowMs: 15*60*1000:时间窗口 15 分钟。max: 100:窗口内最多允许 100 个请求,超出即返回 429。app.use('/user/', apiLimiter):只作用于以/user/开头的路由,实现"按路径精细化限流",其余接口不受影响。
这种中间件方案适合规模较小、非关键的应用(主文档 README.md 原文亦如此建议);生产级场景则应优先考虑 nginx 或云负载均衡器这类基础设施方案。
来自 NGINX 博客的行业佐证
原文档引用了 NGINX 博客 的权威论述,说明限流在安全体系中的多重价值:
限流可用于安全目的,例如减缓暴力破解密码攻击。它可以通过将请求速率限制在真实用户的典型水平(并结合日志)来帮助防御 DDoS 攻击,识别被攻击的目标 URL。更一般地,它被用于保护上游应用服务器免受同一时间过多用户请求的冲击。
这段论述与仓库的实践相互印证:限流既是安全控制(防暴力破解、防 DDoS),也是容量保护(防止上游应用过载崩溃)。仓库中与之配套的还有 登录限流实践,专门针对/login、/admin等高权限路由的字典攻击防护。
实践检查清单
综合原文档与仓库证据,落地限流时应确认以下几点:
- 分层部署:生产环境优先用 nginx / 云负载均衡器 / 云防火墙做第一道粗粒度限流,应用内再做精细化限流(见 README.md)。
- 反代场景记得
app.enable('trust proxy'),否则 IP 识别失效、限流形同虚设。 - 给 Redis 客户端关闭离线队列,避免存储层故障传导到应用层(
enable_offline_queue: false)。 - 敏感路由单独收紧:
/login、/admin等路由的限额应远低于普通 API(参考 登录暴力破解防护 的双限流器模型)。 - 超限统一返回 429,便于客户端与基础设施识别与重试策略匹配。
- 用
blockDuration区分"限速"与"封禁":对持续超限的 IP 主动拉黑一段时间,压制恶意流量。
总结
限流是 Node.js 生产化安全清单中不可跳过的一环:它在基础设施层面由 nginx 或云负载均衡器承担,在应用层面由rate-limiter-flexible(纯 Node.js + Redis,支持集群级全局额度)和express-rate-limit(Express 路由级中间件)落地。原文档提供的两段代码分别覆盖了这两种形态,配合仓库中的 登录限流实践 与 通用安全最佳实践,即可构成一套从防 DDoS 到防暴力破解的完整限流防护体系。
- 文档
- 教程
- 后端
【免费下载链接】nodebestpractices
✅ The Node.js best practices list (July 2026)
相关推荐
Node.js 最佳实践:用中间件或负载均衡器限制并发请求,抵御 DoS 攻击
Node.js 最佳实践:用中间件或负载均衡器限制并发请求,抵御 DoS 攻击 Node.js 应用在面对突发流量或恶意攻击时,可能因同一时刻涌入过多请求而过载
文档教程后端Node.js 安全实践:使用中间件与外部服务实现请求限流(Rate Limiting)
Node.js 安全实践:使用中间件与外部服务实现请求限流(Rate Limiting) 导读 请求限流(Rate Limiting)是保护 Node.js 应
文档教程后端Node.js 限流实战指南:基于 nodebestpractices 使用均衡器或中间件限制并发请求
Node.js 限流实战指南:基于 nodebestpractices 使用均衡器或中间件限制并发请求 本篇指南源自开源项目 nodebestpractices
文档教程后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考