Spring Boot 实现网络限速,一个注解搞定!

概述

本文介绍在 Spring Boot 3 中实现多维度网络带宽限速的完整方案。基于令牌桶算法手动实现核心逻辑,通过自定义HandlerInterceptor拦截请求、HttpServletResponseWrapper包装响应流、RateLimitedOutputStream控制输出速率,实现对文件下载、视频流等场景的精确速度控制。

为什么需要带宽限速

带宽限速与常见的 API 限流不同:限流控制的是请求次数(如每分钟100次),而限速控制的是网络带宽(如每秒200KB)。在实际应用中,带宽限速有着重要的业务价值:

场景一:文件下载服务

对于网盘或资源分发平台,免费用户限制在 200KB/s,VIP 用户提升到 2MB/s,既能保障基础体验,又能激励付费转化。

场景二:视频流媒体

不同清晰度对应不同带宽限制(480P 用 500KB/s,1080P 用 3MB/s),避免高码率视频占用过多服务器带宽。

场景三:API 接口保护

大数据量接口(如导出报表)如果没有带宽控制,单个请求可能占满整个出口带宽,影响其他用户访问。

核心原理:令牌桶算法

令牌桶算法是流量控制的经典方案,其思想非常直观:想象一个桶,系统以固定速率向桶中放入令牌,请求数据时必须从桶中取走对应数量的令牌。

核心参数解析:
  1. 桶容量(Capacity):决定能承受多大突发流量。容量为 200KB 时,即使桶已满,最多也只能连续发送 200KB 数据,之后必须等待令牌补充。

  2. 填充速率(Refill Rate):决定长期平均传输速度。每秒补充 200KB 令牌,意味着平均速度就是 200KB/s。

  3. 分块大小(Chunk Size):影响流量平滑度。将 8KB 数据拆分成 2KB×4 次写入,每次写入之间进行令牌检查,比一次性写入 8KB 更加平滑。

算法流程:

发送数据前:

  1. 计算距离上次补充的时间差

  2. 根据 时间差 × 填充速率 计算新增令牌数

  3. 更新桶中令牌数(不超过容量上限)

发送数据时:

  1. 检查令牌是否足够

  2. 足够:直接扣除令牌,发送数据

  3. 不足:计算 (缺少令牌数 / 填充速率) 得到等待时间,精确等待后发送

技术设计

整体流程

本方案采用拦截器模式,在请求处理的早期阶段完成限速组件的初始化,通过请求属性传递包装后的响应对象。

请求流程: ┌─────────────────────────────────────────────────────────────────────┐ │ 1. DispatcherServlet 分发请求 │ └─────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────┐ │ 2. BandwidthLimitInterceptor.preHandle() │ │ - 解析 @BandwidthLimit 注解 │ │ - 从 BandwidthLimitManager 获取共享 TokenBucket │ │ - 创建 BandwidthLimitResponseWrapper 并存入 request attribute │ └─────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────┐ │ 3. Controller 处理请求 │ │ - 通过 BandwidthLimitHelper.getLimitedResponse() 获取包装后的响应 │ │ - 向响应流写入数据(自动触发限速) │ └─────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────┐ │ 4. BandwidthLimitInterceptor.afterCompletion() │ │ - 清理资源,关闭流 │ └─────────────────────────────────────────────────────────────────────┘
为什么选择 HandlerInterceptor

在 Spring Boot 中实现请求处理,有两种常见方式:FilterHandlerInterceptor。本方案选择HandlerInterceptor的关键原因是:注解解析需要HandlerMethod对象。

Filter 在DispatcherServlet之前执行,此时还没有确定具体的处理方法,无法获取方法上的@BandwidthLimit注解。而HandlerInterceptor在处理器确定后执行,可以通过HandlerMethod精确获取方法级别和类级别的注解信息。

核心组件职责

组件

职责

@BandwidthLimit

声明式注解,配置限速参数

BandwidthLimitInterceptor

拦截请求,解析注解,创建响应包装器

BandwidthLimitManager

管理多维度限速桶(全局/API/用户/IP)

BandwidthLimitResponseWrapper

包装 HttpServletResponse,替换 OutputStream

RateLimitedOutputStream

实现限速逻辑,包装 TokenBucket

TokenBucket

令牌桶算法实现

BandwidthLimitHelper

从请求属性中获取包装后的响应对象

多维度限速实现

本方案支持四种限速维度,满足不同业务场景需求:

全局限速(GLOBAL)

所有请求共享同一个限速桶,适合保护服务器整体出口带宽。例如设置 10MB/s 全局限制,即使有100个并发下载,总带宽也不会超过 10MB/s。

@BandwidthLimit(value = 200, unit = BandwidthUnit.KB, type = LimitType.GLOBAL) @GetMapping("/download/global") public void downloadGlobal(HttpServletResponse response) throws IOException { HttpServletResponse limitedResponse = BandwidthLimitHelper.getLimitedResponse(request, response); // 写入数据... }
API 维度限速(API)

每个接口路径独立限速,不同接口的流量互不影响。/api/file/download限制 500KB/s,/api/video/stream限制 2MB/s,两个接口可以同时达到各自的速度上限。

@BandwidthLimit(value = 500, unit = BandwidthUnit.KB, type = LimitType.API) @GetMapping("/download/file") public void downloadFile(HttpServletResponse response) throws IOException { // 文件下载逻辑 } @BandwidthLimit(value = 2048, unit = BandwidthUnit.KB, type = LimitType.API) @GetMapping("/stream/video") public void streamVideo(HttpServletResponse response) throws IOException { // 视频流逻辑 }
用户维度限速(USER)

根据用户标识(如请求头X-User-Id)进行限速,每个用户独立计算带宽。配合 free 和 vip 参数,可实现差异化服务:

@BandwidthLimit(value = 200, unit = BandwidthUnit.KB, type = LimitType.USER, free = 200, vip = 2048) @GetMapping("/download/user") public void downloadByUser(@RequestHeader("X-User-Type") String userType, HttpServletResponse response) throws IOException { // 根据请求头 X-User-Type 自动应用 200KB/s 或 2MB/s 限速 }
IP 维度限速(IP)

根据客户端 IP 地址限速,防止单个 IP 占用过多带宽。支持代理环境下的 IP 获取(X-Forwarded-ForX-Real-IP)。

@BandwidthLimit(value = 300, unit = BandwidthUnit.KB, type = LimitType.IP) @GetMapping("/download/ip") public void downloadByIp(HttpServletResponse response) throws IOException { // 每个独立 IP 限制 300KB/s }

关键代码实现

1. 令牌桶核心算法

TokenBucket 的核心在于精确的时间计算和令牌补充。使用System.nanoTime()获取纳秒级时间戳,确保高精度速率控制。

public synchronized void acquire(long permits) { // 1. 补充令牌 refill(); // 2. 计算等待时间 if (tokens >= permits) { tokens -= permits; return; } long deficit = permits - tokens; long waitNanos = (deficit * 1_000_000_000L) / refillRate; // 3. 精确等待 sleepNanos(waitNanos); // 4. 等待后消费 tokens = 0; } private void refill() { long now = System.nanoTime(); long elapsedNanos = now - lastRefillTime; long newTokens = (elapsedNanos * refillRate) / 1_000_000_000L; tokens = Math.min(capacity, tokens + newTokens); lastRefillTime = now; }
2. 响应包装器

HttpServletResponseWrapper是 Servlet 规范提供的响应包装基类,通过覆盖getOutputStream()方法返回自定义的限速输出流。

public class BandwidthLimitResponseWrapper extends HttpServletResponseWrapper { privatefinal TokenBucket sharedTokenBucket; // 共享的令牌桶 @Override public ServletOutputStream getOutputStream() throws IOException { if (limitedOutputStream == null && sharedTokenBucket != null) { // 使用共享 TokenBucket,确保多维度统计正确 limitedOutputStream = new RateLimitedOutputStream( super.getOutputStream(), sharedTokenBucket, bandwidthBytesPerSecond ); } return limitedOutputStream; } }
3. 拦截器获取包装响应

拦截器在 preHandle 中创建响应包装器,存储到request attribute,Controller 通过BandwidthLimitHelper获取。

@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { BandwidthLimit annotation = findAnnotation(handler); if (annotation != null) { // 从 Manager 获取共享 TokenBucket TokenBucket bucket = limitManager.getBucket(type, key, capacity, rate); // 创建包装器并存储 BandwidthLimitResponseWrapper wrappedResponse = new BandwidthLimitResponseWrapper(response, bucket, bandwidthBytesPerSecond, chunkSize); request.setAttribute("BandwidthLimitWrappedResponse", wrappedResponse); } return true; }
4. Controller 获取限速响应

Controller 通过BandwidthLimitHelper.getLimitedResponse()获取包装后的响应,所有写入操作都会自动限速。

@GetMapping("/download/global") public void downloadGlobal(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpServletResponse limitedResponse = BandwidthLimitHelper.getLimitedResponse(request, response); limitedResponse.setContentType("application/octet-stream"); limitedResponse.setHeader("Content-Disposition", "attachment; filename=test.bin"); // 写入数据时自动限速 limitedResponse.getOutputStream().write(data); }

参数调优指南

桶容量选择

容量决定突发流量承受能力:

容量设置

突发能力

适用场景

速率 × 0.5

平滑,无突发

流量控制严格的场景

速率 × 1.0

允许 1 秒突发

默认推荐值

速率 × 2.0

允许 2 秒突发

需要良好首屏加载

// 注解配置 @BandwidthLimit(value = 200, unit = BandwidthUnit.KB, capacityMultiplier = 1.0)
分块大小选择

分块大小影响流量平滑度,经验公式:chunkSize = bandwidth / 50

带宽

推荐分块

理由

200 KB/s

1-4 KB

小分块保证平滑

1 MB/s

4-8 KB

平衡平滑与性能

5 MB/s+

8-16 KB

减少系统调用开销

// 自动计算(推荐) @BandwidthLimit(value = 200, unit = BandwidthUnit.KB, chunkSize = -1) // 手动指定 @BandwidthLimit(value = 200, unit = BandwidthUnit.KB, chunkSize = 4096)

总结

本文基于令牌桶算法,通过HandlerInterceptor + HttpServletResponseWrapper,在 Spring Boot 中实现了多维度带宽限速。

支持全局/API/用户/IP 四种限速维度,提供实时统计监控,适用于API接口保护、文件下载、视频流等场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1189356.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

libero ProASIC3 A3P250 JTAG-DirectC 源码分析三 dp_program_from

libero ProASIC3 A3P250 JTAG-DirectC 源码分析三 dp_program_from

2026年市场评价高的保温装饰一体化板公司怎么选,石墨聚苯板保温装饰一体板,保温装饰一体化板生产商如何选 - 品牌推荐师

引言 保温装饰一体化板作为建筑外墙节能的核心材料,兼具保温隔热、装饰美观与防火安全功能,是推动绿色建筑发展的关键环节。尤其在“双碳”目标下,其市场需求持续攀升,但行业准入门槛低导致产品质量参差不齐,采购…

2026年国内专业的一体板订制厂家如何选,聚氨酯保温装饰一体板/一体板/石墨聚苯板保温装饰一体板,一体板品牌电话 - 品牌推荐师

评测背景:外墙装饰一体板市场迎来品质与服务双升级 随着建筑节能政策深化与绿色建筑需求激增,外墙装饰一体板作为集保温、装饰、防火功能于一体的新型建材,已成为住宅、商业及公共建筑的核心选择。然而,市场品牌混…

2026年流量计市场新动态:实力厂家高压流量计精选,插入式超声波流量计/管道式电磁流量计,流量计制造企业哪家好 - 品牌推荐师

行业背景与市场趋势 随着工业自动化与能源管理需求的持续攀升,高压流量计作为过程控制的核心设备,其市场正经历技术迭代与需求分化的双重变革。一方面,石油、化工、天然气等传统行业对高压介质测量的精度与稳定性提…

全栈小能手的烦恼:键盘敲累了还要开会

全栈小能手的烦恼:键盘敲累了还要开会如果你问我,什么时候意识到自己已经不再是“纯程序员”了?不是第一次写前端,也不是第一次带新人,而是——有一天,我发现自己一天没怎么敲代码,却异常疲惫。…

2025年行业内诚信的一对一家教老师怎么选择,科学家教/师范家教/一对一家教/语文家教/家救,一对一家教老师推荐排行榜 - 品牌推荐师

随着个性化教育需求的持续增长,一对一家教市场已成为家长提升孩子学业竞争力的重要选择。然而,行业分散化、服务标准化缺失等问题导致家长选择时面临信息不对称、效果难保障等痛点。据第三方教育平台统计,2024年杭州…

《把脉行业与技术趋势》-68-行业周期律以及背后的底层逻辑

行业周期律,是指特定行业在时间维度上呈现出的规律性兴衰更替现象。它并非随机波动,而是由经济、技术、政策、供需、资本等多重力量共同作用的结果。理解行业周期律及其底层逻辑,是投资者、创业者、职场人规避风险、捕捉机遇的核心能力。一、…

2026年纯铝锭厂家选购推荐/铝板,铝锭,铝箔,高温铝箔,包装用铝箔 - 品牌策略师

2026年纯铝锭厂家选购推荐/铝板,铝锭,铝箔,高温铝箔,包装用铝箔当前,全球制造业持续复苏,新能源汽车、航空航天、绿色建筑等高端领域对轻量化材料的需求不断攀升,纯铝锭作为基础工业原料,其市场前景广阔。随着…

可控生成策略在大语言模型摘要生成中的应用

运行效果:https://lunwen.yeel.cn/view.php?id=5810 可控生成策略在大语言模型摘要生成中的应用摘要:随着人工智能技术的快速发展,大语言模型在自然语言处理领域取得了显著成果。然而,在摘要生成方面,大语言模型…

2026年高口碑蒸汽发生器品牌TOP榜:全预混节能先锋、电蒸汽高效代表、燃气蒸汽发生器实力厂商全解析! - 品牌推荐大师1

一、行业背景与市场趋势​ 随着全球工业自动化与环保政策的推进,蒸汽发生器作为工业热能核心设备,市场需求持续增长。2026年,中国蒸汽发生器市场规模预计突破200亿元,其中电蒸汽、燃气蒸汽、全预混低氮锅炉成为主流…

AI自动化智能体与工作流平台直播课

关注 霍格沃兹测试学院公众号,回复「资料」, 领取人工智能测试开发技术合集每天埋头于重复性工作,点击、复制、粘贴、测试,你是否感到时间被无形吞噬?当同事们早早下班,你是否还在为明天的汇报手动整理最后一份数据报告…

rector-rules - 提供标准化的常量、变量、函数、类、属性和方法命名以及其他 Rector 规则

rector-rules - 提供标准化的常量、变量、函数、类、属性和方法命名以及其他 Rector 规则之前写过用 Rector 《统一规范化代码的命名风格》,现在已经整理发布为 Composer 包了。 rector-rules - 提供标准化的常量、变…

哈尔滨市英语雅思培训辅导机构推荐、2026权威出国雅思课程中心学校口碑排行榜 - 苏木2025

在雅思培训市场竞争激烈的当下,哈尔滨众多考生在选课过程中普遍面临优质教育机构难甄别、提分技巧不系统、个性化方案缺失等痛点。想要高效备战考试,斩获高分,选择一家靠谱的机构至关重要。基于此,我们开展全网深度…

避开Context

说明 之前脑抽想试试Context。 果不其然,和安卓里面的context一样都挺难用。 Context看上去可能很好,但是在维护时,context一点也不直观,跳到Context中看不到任何的数据和方法,需要再去找层级,传参。 结果还不如…

收藏!35+程序员转行大模型全攻略:从入门到求职落地,少走90%弯路

在技术迭代日新月异的当下,大模型领域凭借其广阔的应用场景、持续攀升的市场需求以及极具吸引力的薪资待遇,已然成为程序员群体转型的热门优选赛道。对于35岁以上的程序员而言,尽管面临着精力分配失衡、技术代际断层、职场竞争加剧等现实挑战…

哈尔滨市英语雅思培训辅导机构推荐:2026权威出国雅思课程中心学校口碑排行榜 - 苏木2025

在全球化留学热潮下,雅思考试已成为哈尔滨学子通往海外名校的核心门槛,优质的雅思培训则是斩获高分、实现留学目标的关键支撑。然而当前哈尔滨雅思培训市场鱼龙混杂,考生及家长普遍面临诸多痛点:难以在海量教育机构…

图像识别与语音融合的无障碍辅助系统

运行效果:https://lunwen.yeel.cn/view.php?id=5809 图像识别与语音融合的无障碍辅助系统摘要:随着科技的不断发展,图像识别和语音识别技术逐渐成熟,为无障碍辅助系统的发展提供了新的可能。本论文旨在设计并实现…

远程固件升级服务(自有服务器,使用libfota2扩展库)

一、FOTA 概述 FOTA 即远程升级功能,此功能可以让客户在不方便大量线刷升级(设备不在身边/量产 PCB 没引出 USB/需要大批量进行功能升级)的情况下,快速进行底层固件/脚本/脚本 底层固件的远程更新。 LuatOS 开发模式下,固件分为两部分&…

阳光电动力:以“技术+价值”双重优势,重新定义车载电源制造商新标杆 - 博客万

在中国新能源汽车产业迈向规模化、智能化与全球化的关键阶段,车载电源作为电动车的“能源枢纽”,其性能、可靠性与系统价值直接影响整车的竞争力与用户体验。伴随电动车渗透率持续攀升、续航焦虑逐步化解,市场对车载…

哈尔滨市英语雅思培训辅导机构推荐;2026权威出国雅思课程中心学校口碑排行榜 - 苏木2025

在2026年留学热潮持续升温的背景下,雅思考试成为学子通往海外名校的关键门槛,而选择优质靠谱的雅思培训教育机构、获取实用提分技巧与个性化备考方案,成为多数哈尔滨考生及家长的核心诉求。当前哈尔滨市雅思培训市场…