最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

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

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

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

客戶端發(fā)起請求
     ↓
download(...) 方法被調(diào)用
     ↓
從 Redis 增加并發(fā)數(shù) DOWNLOAD_CONCURRENT_KEY
     ↓
根據(jù)并發(fā)數(shù)計算限速值(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ā)計數(shù)器
Long currentConcurrent = redisTemplate.opsForValue().increment(DOWNLOAD_CONCURRENT_KEY);
// 更新過期時間
redisTemplate.expire(DOWNLOAD_CONCURRENT_KEY, EXPIRE_TIME_IN_SECONDS, TimeUnit.SECONDS);
// 計算限速值
int speedLimit = getDownloadSpeedLimit(currentConcurrent.intValue());
  • increment(...):將 Redis 中的鍵值增加 1,表示有新的下載開始。
  • expire(...):為這個 key 設(shè)置過期時間,防止僵尸數(shù)據(jù)。
  • getDownloadSpeedLimit(...):根據(jù)當(dāng)前并發(fā)數(shù)計算單個用戶的限速值。

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 個用戶下載,那他可以使用全部 5MB/s;
  • 如果有 5 個用戶同時下載,每人最多只能用到 1MB/s;
  • 即使并發(fā)數(shù)很多,也保證最低 50KB/s,避免卡死。

3?? 實際限速邏輯(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ā)給客戶端);
  • 累計已發(fā)送的字節(jié)數(shù);
  • 如果累計發(fā)送的數(shù)據(jù)超過設(shè)定的 bytesPerSecond(如 1MB),就判斷這一秒還沒過去,那么線程休眠剩余時間;
  • 重置計數(shù)器和開始時間,進(jìn)入下一輪循環(huán)。

示例:限速 1MB/s

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

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

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

舉個例子:

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

通過這種方式,系統(tǒng)會自動平衡所有用戶的下載速度,不會因為某一個用戶占用過多帶寬而導(dǎo)致其他用戶下載很慢。

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

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

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

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

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

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

?? 九、結(jié)語

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

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

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

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

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

相關(guān)文章

  • spring boot與spring mvc的區(qū)別及功能介紹

    spring boot與spring mvc的區(qū)別及功能介紹

    這篇文章主要介紹了spring boot與spring mvc的區(qū)別是什么以及spring boot和spring mvc功能介紹,感興趣的朋友一起看看吧
    2018-02-02
  • SpringBoot整合iText7導(dǎo)出PDF及性能優(yōu)化方式

    SpringBoot整合iText7導(dǎo)出PDF及性能優(yōu)化方式

    在SpringBoot項目中整合iText7庫以導(dǎo)出PDF文件,不僅能夠滿足報告生成需求,而且可以處理復(fù)雜的文檔布局與樣式,整合步驟包括添加Maven依賴、編寫PDF生成代碼,性能優(yōu)化方面,建議使用流式處理、緩存樣式與字體、優(yōu)化HTML/CSS結(jié)構(gòu)、采用異步處理
    2024-09-09
  • Java編程使用Runtime和Process類運行外部程序的方法

    Java編程使用Runtime和Process類運行外部程序的方法

    這篇文章主要介紹了Java編程使用Runtime和Process類運行外部程序的方法,結(jié)合實例形式分析了java使用Runtime.getRuntime().exec()方法運行外部程序的常見情況與操作技巧,需要的朋友可以參考下
    2017-08-08
  • 微信開發(fā)準(zhǔn)備第二步 springmvc mybatis項目結(jié)構(gòu)搭建

    微信開發(fā)準(zhǔn)備第二步 springmvc mybatis項目結(jié)構(gòu)搭建

    這篇文章主要為大家詳細(xì)介紹了微信開發(fā)準(zhǔn)備第二步,springmvc和mybatis項目結(jié)構(gòu)的搭建,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • JDK8時間相關(guān)類超詳細(xì)總結(jié)(含多個實例)

    JDK8時間相關(guān)類超詳細(xì)總結(jié)(含多個實例)

    jdk1.8的一些新特性簡化了代碼的寫法,減少了部分開發(fā)量,下面這篇文章主要給大家介紹了關(guān)于JDK8時間相關(guān)類超詳細(xì)總結(jié),文中包含了多個實例代碼,需要的朋友可以參考下
    2023-01-01
  • 分享java打印簡單圖形的實現(xiàn)代碼

    分享java打印簡單圖形的實現(xiàn)代碼

    這篇文章主要分享給大家運用java打印簡單圖形:三角形,菱形,四邊形,需要的朋友可以參考下
    2015-07-07
  • MybatisPlus中的刪除和邏輯刪除及區(qū)別介紹

    MybatisPlus中的刪除和邏輯刪除及區(qū)別介紹

    這篇文章主要介紹了MybatisPlus中的刪除和邏輯刪除的相關(guān)知識,刪除又分為邏輯刪除和物理刪除,那么它們有什么區(qū)別呢?在本文給大家詳細(xì)介紹,感興趣的朋友跟隨小編一起看看吧
    2020-08-08
  • 解決mybatisplus的分頁插件和條件構(gòu)造器自定義SQL遇到的BUG

    解決mybatisplus的分頁插件和條件構(gòu)造器自定義SQL遇到的BUG

    這篇文章主要介紹了解決mybatisplus的分頁插件和條件構(gòu)造器自定義SQL遇到的BUG,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot Mybatis多數(shù)據(jù)源配置全過程

    SpringBoot Mybatis多數(shù)據(jù)源配置全過程

    本文詳細(xì)介紹了如何在Java項目中配置多數(shù)據(jù)源,包括配置文件設(shè)置、多數(shù)據(jù)源配置類、MyBatis配置等,通過兩種不同的方式配置primary和secondary數(shù)據(jù)源,展示了如何處理Mapper接口文件和.xml文件不在同一目錄下的情況,并使用@Primary注解指定默認(rèn)數(shù)據(jù)源
    2025-11-11
  • jvm-jstack常用的用法示例

    jvm-jstack常用的用法示例

    jstack 是一個常用的用于分析 Java 進(jìn)程的工具。它可以顯示 Java 進(jìn)程中所有線程狀態(tài)和堆棧信息,幫助定位 Java 進(jìn)程中的問題,這篇文章主要介紹了jvm-jstack常用的用法示例,需要的朋友可以參考下
    2023-06-06

最新評論

图片| 包头市| 临城县| 梅河口市| 贡山| 保康县| 百色市| 临夏县| 海城市| 平安县| 秀山| 通道| 漾濞| 嘉黎县| 汉阴县| 开阳县| 会昌县| 平安县| 福建省| 龙州县| 改则县| 婺源县| 南丹县| 南城县| 安龙县| 抚远县| 绥化市| 来安县| 大洼县| 天长市| 海丰县| 东至县| 尼勒克县| 化州市| 大城县| 郎溪县| 神农架林区| 金溪县| 博爱县| 灵台县| 柳林县|