欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot下載接口限速功能實(shí)現(xiàn)

 更新時(shí)間:2025年06月17日 16:56:47   作者:chen.@-@  
通過Redis統(tǒng)計(jì)并發(fā)數(shù)動(dòng)態(tài)調(diào)整每個(gè)用戶帶寬,核心邏輯為每秒讀取并發(fā)送限定數(shù)據(jù)量,防止單用戶占用過多資源,確保整體下載均衡且高效,本文給大家介紹springboot下載接口限速功能實(shí)現(xiàn),感興趣的朋友一起看看吧

當(dāng)然可以!我們來結(jié)合你提供的代碼和限速邏輯,詳細(xì)說明整個(gè)“下載限速”功能是如何實(shí)現(xiàn)的。

?? 一、整體目標(biāo)

我們要實(shí)現(xiàn)的功能是:

限制每個(gè)用戶的下載速度(例如1MB/s),并根據(jù)當(dāng)前并發(fā)下載用戶數(shù)動(dòng)態(tài)調(diào)整限速值。

?? 二、涉及的主要類/方法

類/方法功能
FileUtil.limitDownloadSpeed(...)核心限速方法,控制每秒發(fā)送的數(shù)據(jù)量
download(...)下載入口,獲取文件路徑、設(shè)置響應(yīng)頭等
limitReadFile(...)調(diào)用限速方法執(zhí)行下載
Redis 操作統(tǒng)計(jì)并發(fā)下載數(shù),用于動(dòng)態(tài)限速

? 三、核心流程圖解(簡(jiǎn)化)

客戶端發(fā)起請(qǐng)求
     ↓
download(...) 方法被調(diào)用
     ↓
從 Redis 增加并發(fā)數(shù) DOWNLOAD_CONCURRENT_KEY
     ↓
根據(jù)并發(fā)數(shù)計(jì)算限速值(getDownloadSpeedLimit)
     ↓
調(diào)用 limitReadFile(...) 開始下載文件
     ↓
limitReadFile(...) 內(nèi)部調(diào)用 FileUtil.limitDownloadSpeed(...)
     ↓
讀取文件內(nèi)容 → 分段寫入輸出流 → 控制每秒發(fā)送的數(shù)據(jù)量
     ↓
下載完成或客戶端斷開連接
     ↓
finally 中減少 Redis 的并發(fā)數(shù)

?? 四、關(guān)鍵代碼詳解

1?? 設(shè)置并發(fā)數(shù) + 獲取限速值(download(...) 方法中)

// 增加并發(fā)計(jì)數(shù)器
Long currentConcurrent = redisTemplate.opsForValue().increment(DOWNLOAD_CONCURRENT_KEY);
// 更新過期時(shí)間
redisTemplate.expire(DOWNLOAD_CONCURRENT_KEY, EXPIRE_TIME_IN_SECONDS, TimeUnit.SECONDS);
// 計(jì)算限速值
int speedLimit = getDownloadSpeedLimit(currentConcurrent.intValue());
  • increment(...):將 Redis 中的鍵值增加 1,表示有新的下載開始。
  • expire(...):為這個(gè) key 設(shè)置過期時(shí)間,防止僵尸數(shù)據(jù)。
  • getDownloadSpeedLimit(...):根據(jù)當(dāng)前并發(fā)數(shù)計(jì)算單個(gè)用戶的限速值。

2?? 限速策略函數(shù) getDownloadSpeedLimit(...)

private int getDownloadSpeedLimit(int concurrentCount) {
    int totalBandwidth = 1024 * 1024 * 5; // 總帶寬 5MB/s
    int perUserSpeed = totalBandwidth / Math.max(1, concurrentCount);
    return Math.max(perUserSpeed, 1024 * 50); // 最低限速 50KB/s
}
  • 如果當(dāng)前只有 1 個(gè)用戶下載,那他可以使用全部 5MB/s;
  • 如果有 5 個(gè)用戶同時(shí)下載,每人最多只能用到 1MB/s;
  • 即使并發(fā)數(shù)很多,也保證最低 50KB/s,避免卡死。

3?? 實(shí)際限速邏輯(FileUtil.limitDownloadSpeed(...))

public static void limitDownloadSpeed(InputStream in, OutputStream out, int bytesPerSecond) throws IOException {
    byte[] buffer = new byte[BUFFER_SIZE]; // 默認(rèn)是 1024 字節(jié)
    int bytesRead;
    long bytesSent = 0;
    long startTime = System.currentTimeMillis();
    while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
        bytesSent += bytesRead;
        if (bytesSent >= bytesPerSecond) {
            long elapsedTime = System.currentTimeMillis() - startTime;
            if (elapsedTime < 1000) {
                Thread.sleep(1000 - elapsedTime);
            }
            bytesSent = 0;
            startTime = System.currentTimeMillis();
        }
    }
}

這段代碼的核心邏輯是:

  • 每次從輸入流讀取一塊數(shù)據(jù)(默認(rèn) 1KB);
  • 將這塊數(shù)據(jù)寫入輸出流(即發(fā)給客戶端);
  • 累計(jì)已發(fā)送的字節(jié)數(shù);
  • 如果累計(jì)發(fā)送的數(shù)據(jù)超過設(shè)定的 bytesPerSecond(如 1MB),就判斷這一秒還沒過去,那么線程休眠剩余時(shí)間;
  • 重置計(jì)數(shù)器和開始時(shí)間,進(jìn)入下一輪循環(huán)。

示例:限速 1MB/s

  • 第一次循環(huán):
    • 讀取了 1024 × 1000 = 1MB 數(shù)據(jù);
    • 發(fā)送完后發(fā)現(xiàn)只用了 500ms;
    • 休眠 500ms;
    • 清空計(jì)數(shù)器,重新開始下一秒的限速。

這樣就能保證 每秒最多發(fā)送 1MB 數(shù)據(jù)。

?? 五、如何做到“并發(fā)越多,限速越小”?

舉個(gè)例子:

并發(fā)數(shù)總帶寬(假設(shè))每人可用帶寬
15MB/s5MB/s
25MB/s2.5MB/s
55MB/s1MB/s
105MB/s500KB/s
1005MB/s50KB/s(最小限制)

通過這種方式,系統(tǒng)會(huì)自動(dòng)平衡所有用戶的下載速度,不會(huì)因?yàn)槟骋粋€(gè)用戶占用過多帶寬而導(dǎo)致其他用戶下載很慢。

?? 六、完整流程總結(jié)

步驟描述
1. 客戶端請(qǐng)求下載請(qǐng)求 /file/download/[code]
2. 服務(wù)器記錄并發(fā)數(shù)使用 Redis INCR 增加并發(fā)計(jì)數(shù)
3. 計(jì)算限速值根據(jù)并發(fā)數(shù)平均分配總帶寬
4. 執(zhí)行限速下載使用 limitDownloadSpeed(...) 控制每秒發(fā)送的字節(jié)數(shù)
5. 客戶端中斷或下載完成使用 FINALLY 減少 Redis 中的并發(fā)數(shù)
6. 自動(dòng)清理Redis key 設(shè)置了過期時(shí)間,防止數(shù)據(jù)殘留

? 七、優(yōu)點(diǎn)總結(jié)

特性是否支持說明
靜態(tài)限速? 是可以為每個(gè)用戶固定限速
動(dòng)態(tài)限速? 是根據(jù)并發(fā)數(shù)自動(dòng)調(diào)整限速
Redis 支持? 是實(shí)現(xiàn)并發(fā)統(tǒng)計(jì)
異常安全? 是finally 中釋放資源
可擴(kuò)展性強(qiáng)? 是可加入 VIP 用戶、IP 限速等功能

?? 八、可選優(yōu)化建議(進(jìn)階)

優(yōu)化點(diǎn)說明
緩沖區(qū)增大把 BUFFER_SIZE 改成 64KB 或 128KB 提升性能
更精細(xì)限速每 100ms 控制一次限速,而不是每秒
VIP 用戶優(yōu)先不同用戶組使用不同限速策略
斷點(diǎn)續(xù)傳支持 Range 請(qǐng)求頭,允許暫停繼續(xù)下載
日志記錄記錄每次下載的 IP、速度、時(shí)長(zhǎng)等信息
帶寬監(jiān)控顯示實(shí)時(shí)帶寬使用情況、并發(fā)數(shù)等

?? 九、結(jié)語

你現(xiàn)在擁有的是一套完整的、可落地的 “并發(fā)感知型下載限速系統(tǒng)”,它具備以下特點(diǎn):

  • ? 支持靜態(tài)限速
  • ? 支持動(dòng)態(tài)限速(基于并發(fā))
  • ? 使用 Redis 統(tǒng)計(jì)并發(fā)
  • ? 限速邏輯清晰高效
  • ? 安全可靠,異常處理完善

如果你希望我?guī)湍氵M(jìn)一步擴(kuò)展功能,比如:

  • 支持 VIP 用戶限速更高
  • 加入日志記錄模塊
  • 實(shí)現(xiàn)斷點(diǎn)續(xù)傳
  • 添加帶寬監(jiān)控頁面

到此這篇關(guān)于springboot下載接口限速功能實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot下載限速內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入了解Spring的事務(wù)傳播機(jī)制

    深入了解Spring的事務(wù)傳播機(jī)制

    Spring事務(wù)傳播機(jī)制是指,包含多個(gè)事務(wù)的方法在相互調(diào)用時(shí),事務(wù)是如何在這些方法間傳播的。本文通過示例詳細(xì)介紹了Spring的事務(wù)傳播機(jī)制,需要的可以參考一下
    2022-09-09
  • 接口重試的7種常用方案詳細(xì)介紹

    接口重試的7種常用方案詳細(xì)介紹

    這篇文章主要為大家詳細(xì)介紹了接口重試的7種常用方案,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以根據(jù)需求選擇
    2025-03-03
  • Spring Cloud中各組件超時(shí)總結(jié)

    Spring Cloud中各組件超時(shí)總結(jié)

    在大家學(xué)習(xí)spring cloud的時(shí)候組件是必不可少的一部分,下面這篇文章主要給大家介紹了關(guān)于Spring Cloud中各組件超時(shí)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-11-11
  • Java單例模式簡(jiǎn)單示例

    Java單例模式簡(jiǎn)單示例

    這篇文章主要介紹了Java單例模式,結(jié)合實(shí)例形式簡(jiǎn)單分析了java單例模式的定義與使用技巧,需要的朋友可以參考下
    2017-06-06
  • springBoot2.X配置全局捕獲異常的操作

    springBoot2.X配置全局捕獲異常的操作

    這篇文章主要介紹了springBoot2.X配置全局捕獲異常的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 淺談MyBatis所有的jdbcType類型

    淺談MyBatis所有的jdbcType類型

    在Mybatis中JdbcType類型是一個(gè)枚舉類型,它包含了所有的JDBC數(shù)據(jù)類型,如VARCHAR、INTEGER、DATE等,本文主要介紹了淺談MyBatis所有的jdbcType類型,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-06-06
  • Springcloud sentinel安裝和使用方法解析

    Springcloud sentinel安裝和使用方法解析

    這篇文章主要介紹了Springcloud sentinel安裝和使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • 詳解JAVA中接口的定義和接口的實(shí)現(xiàn)

    詳解JAVA中接口的定義和接口的實(shí)現(xiàn)

    這篇文章主要介紹了JAVA中接口的定義和接口的實(shí)現(xiàn),文中講解非常細(xì)致,配合代碼更好的幫大家學(xué)習(xí)參考,感興趣的朋友可以了解下
    2020-06-06
  • 詳解JVM棧溢出和堆溢出

    詳解JVM棧溢出和堆溢出

    今天帶大家學(xué)習(xí)的是Java的相關(guān)知識(shí),文章圍繞著JVM棧溢出和堆溢出展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 淺談springboot自動(dòng)裝配原理

    淺談springboot自動(dòng)裝配原理

    作為Spring Boot的精髓,自動(dòng)配置原理首當(dāng)其沖.今天就帶大家了解一下springboot自動(dòng)裝配的原理,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05

最新評(píng)論