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

springboot X-Accel-Redirect 大文件下載實(shí)現(xiàn)

 更新時(shí)間:2023年06月09日 11:50:14   作者:Mr-Wanter  
本文主要介紹了springboot X-Accel-Redirect 大文件下載實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

文件下載的方式:

  • nginx代理附件路徑,直接訪問(wèn)。無(wú)法控制用戶(hù)的權(quán)限。
  • 服務(wù)端流式讀取文件內(nèi)容。這個(gè)過(guò)程需要后端進(jìn)程將文件讀取到內(nèi)存中然后再發(fā)給用戶(hù),會(huì)造成很大的資源開(kāi)銷(xiāo)。如果你文件較大,可能會(huì)超時(shí),并且會(huì)占用比較大的內(nèi)存,當(dāng)用戶(hù)下載量很大時(shí)有可能造成程序的崩潰。
  • 服務(wù)端權(quán)限控制后通過(guò)X-Accel-Redirect 重定向到nginx代理地址。傳輸快、服務(wù)器IO低,但是無(wú)法跟蹤下載進(jìn)度。

一、什么是 X-Sendfile?

X-Sendfile是一種將文件下載請(qǐng)求由后端應(yīng)用轉(zhuǎn)交給前端web服務(wù)器處理的機(jī)制,它可以消除后端程序既要讀文件又要處理發(fā)送的壓力,從而顯著提高服務(wù)器效率,特別是處理大文件下載的情形下。

X-Sendfile 通過(guò)一個(gè)特定的 header 來(lái)實(shí)現(xiàn):在 X-Sendfile 頭中指定一個(gè)文件的地址來(lái)通告前端 web 服務(wù)器。當(dāng) web 服務(wù)器檢測(cè)到后端發(fā)送的這個(gè) header 后,它將忽略后端的其他輸出,而使用自身的組件(包括 緩存頭 和 斷點(diǎn)重連 等優(yōu)化)機(jī)制將文件發(fā)送給用戶(hù)。

不過(guò),在使用 X-Sendfile 之前,我們必須明白這并不是一個(gè)標(biāo)準(zhǔn)特性,在默認(rèn)情況下它是被大多數(shù) web 服務(wù)器禁用的。而不同的 web 服務(wù)器的實(shí)現(xiàn)也不一樣,包括規(guī)定了不同的 X-Sendfile 頭格式。如果配置失當(dāng),用戶(hù)可能下載到 0 字節(jié)的文件。

nginx: X-Accel-Redirect

squid: X-Accelerator-Vary

apache: X-Sendfile

lighttpd: X-Sendfile/X-LIGHTTPD-send-file

使用X-Sendfile的缺點(diǎn)是你失去對(duì)文件傳輸機(jī)制的控制,后臺(tái)不知道文件是否下載成功。

Nginx 默認(rèn)支持該特性 ,不需要加載額外的模塊。只是實(shí)現(xiàn)有些不同, 需要發(fā)送的 HTTP 頭為 X-Accel-Redirect。

X-Accel-Redirect:
這個(gè)功能允許你在后端處理權(quán)限,日志或任何你想干的,Nginx提供內(nèi)容服務(wù)給終端用戶(hù)從重定向后的路徑,因此可以釋放后端去處理其他請(qǐng)求(直接由Nginx提供IO,而不是后端服務(wù))。這個(gè)功能類(lèi)似X-Sendfile 。

二、相關(guān)請(qǐng)求頭說(shuō)明

X-Accel-Limit-Rate
限制下載速度,單位字節(jié)。默認(rèn)不限速度。

X-Accel-Buffering
設(shè)置此連接的代理緩存,將此設(shè)置為no將允許適用于Comet和HTTP流式應(yīng)用程序的無(wú)緩沖響應(yīng)。將>此設(shè)置為yes將允許響應(yīng)被緩存。默認(rèn)yes。

X-Accel-Expires
如果已傳輸過(guò)的文件被緩存下載,設(shè)置Nginx文件緩存過(guò)期時(shí)間,單位秒。默認(rèn)不過(guò)期。

X-Accel-Charset
設(shè)置文件字符集,默認(rèn)UTF-8

三、實(shí)現(xiàn)步驟

前置條件:

需要前端請(qǐng)求的Referer 和 nginx 在同一臺(tái)機(jī)器,或者nginx代理到最終附件服務(wù)器的nginx地址nginx代理附件地址和附件下載服務(wù)(保證代理和服務(wù)在同一個(gè)ip 端口下)

location /protected_files {
? ? internal; ? ? # internal 表示這個(gè)路徑只能在 Nginx 內(nèi)部訪問(wèn),不能用瀏覽器直接訪問(wèn)防止未授權(quán)的下載
? ? alias /mnt/files;
}
location /gsdss-api/ {
? ? ? ?#OPTIONS請(qǐng)求處理
? ? ? ?if ($request_method = 'OPTIONS') {
? ? ? ? ? ? ? ?add_header 'Access-Control-Max-Age' 1728000;
? ? ? ? ? ? ? ?add_header Access-Control-Allow-Origin *;
? ? ? ? ? ? ? ?add_header Access-Control-Allow-Credentials true;
? ? ? ? ? ? ? ?add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
? ? ? ? ? ? ? ?add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token,orgcode';
? ? ? ? ? ? ? ?return 200;
? ? ? ?}
? ? ? ?proxy_pass 網(wǎng)關(guān)地址;
? ? ? ?proxy_set_header Host $host;
? ? ? ?proxy_set_header X-Real-IP $remote_addr;
? ? ? ?proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
? ? ? ?client_max_body_size 100m;
? ? ? ?proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}

java處理鑒權(quán)后直接重定向到nginx代理地址

    public void downloadByLink(HttpServletResponse response, String fileId) {
        //查詢(xún)附件信息
        AttachmentResp resp = attachmentService.findByAttachId(fileId);
        //鑒權(quán)實(shí)際已經(jīng)通過(guò)gateway完成
        try {
            String fileName = URLEncoder.encode(resp.getFileName(), "UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("X-Accel-Redirect", "/upload" + resp.getPath()); //設(shè)置URI給nginx進(jìn)行內(nèi)部的跳轉(zhuǎn)
            response.setHeader("X-Accel-Limit-Rat", "202400"); //限速
        } catch (UnsupportedEncodingException e) {
            log.error("文件下載失敗 ", e);
            throw new BusinessException("文件下載失敗");
        }
    }

總結(jié)

常規(guī)請(qǐng)求路徑

前端nginx:前端訪問(wèn)nginx代理網(wǎng)關(guān)路徑

后端nginx:

  • 代理網(wǎng)關(guān)路徑轉(zhuǎn)發(fā)到實(shí)際網(wǎng)關(guān)地址
  • 網(wǎng)關(guān)分發(fā)到附件服務(wù)
  • 附件服務(wù)處理請(qǐng)求

為了保證nginx代理的下載路徑和附件下載服務(wù)在同一ip和端口那么這個(gè)nginx代理需要2層實(shí)現(xiàn)

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

相關(guān)文章

  • 詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式

    詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式

    這篇文章主要介紹了詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Mockito如何mock靜態(tài)方法問(wèn)題

    Mockito如何mock靜態(tài)方法問(wèn)題

    本文介紹了如何在Mockito 3.4.0版本及以上版本中mock靜態(tài)方法,包括如何在pom文件中添加相關(guān)jar包、如何使用Mockito.mockStatic(Class mockClass)方法以及注意事項(xiàng)等
    2025-02-02
  • Java對(duì)象和Map之間相互轉(zhuǎn)換的五種方法

    Java對(duì)象和Map之間相互轉(zhuǎn)換的五種方法

    在Java開(kāi)發(fā)中,經(jīng)常需要將Java對(duì)象轉(zhuǎn)換成Map,或者反過(guò)來(lái)將Map轉(zhuǎn)換成Java對(duì)象,這種轉(zhuǎn)換在很多場(chǎng)景下都非常有用,比如在序列化和反序列化過(guò)程中、在數(shù)據(jù)傳輸和持久化時(shí)、或者在進(jìn)行對(duì)象屬性的批量操作時(shí),本文將介紹幾種不同的方法來(lái)實(shí)現(xiàn)Java對(duì)象和Map之間的相互轉(zhuǎn)換
    2025-02-02
  • 如何解決java.util.concurrent.CancellationException問(wèn)題

    如何解決java.util.concurrent.CancellationException問(wèn)題

    這篇文章主要介紹了如何解決java.util.concurrent.CancellationException問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java HtmlEmail 郵件發(fā)送的簡(jiǎn)單實(shí)現(xiàn)代碼

    Java HtmlEmail 郵件發(fā)送的簡(jiǎn)單實(shí)現(xiàn)代碼

    下面小編就為大家?guī)?lái)一篇Java HtmlEmail 郵件發(fā)送的簡(jiǎn)單實(shí)現(xiàn)代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • 使用Feign實(shí)現(xiàn)微服務(wù)間文件傳輸

    使用Feign實(shí)現(xiàn)微服務(wù)間文件傳輸

    這篇文章主要為大家詳細(xì)介紹了使用Feign實(shí)現(xiàn)微服務(wù)間文件傳輸,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • 淺談java隨機(jī)數(shù)的陷阱

    淺談java隨機(jī)數(shù)的陷阱

    這篇文章主要介紹了淺談java隨機(jī)數(shù)的陷阱,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 使用Java實(shí)現(xiàn)簽字功能的示例代碼

    使用Java實(shí)現(xiàn)簽字功能的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)簽字功能,同時(shí)支持將簽字圖像保存為PNG格式和將簽字添加到PDF文檔中,感興趣的可以了解下
    2024-02-02
  • mybatis-plus指定字段模糊查詢(xún)的實(shí)現(xiàn)方法

    mybatis-plus指定字段模糊查詢(xún)的實(shí)現(xiàn)方法

    最近項(xiàng)目中使用springboot+mybatis-plus來(lái)實(shí)現(xiàn),所以下面這篇文章主要給大家介紹了關(guān)于mybatis-plus實(shí)現(xiàn)指定字段模糊查詢(xún)的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • SpringBoot登錄、退出、獲取用戶(hù)信息的session處理方案

    SpringBoot登錄、退出、獲取用戶(hù)信息的session處理方案

    這篇文章主要介紹了SpringBoot登錄、退出、獲取用戶(hù)信息的session處理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08

最新評(píng)論

合作市| 合水县| 益阳市| 澎湖县| 西贡区| 宁德市| 永嘉县| 肇东市| 茶陵县| 唐河县| 双江| 迭部县| 通城县| 祁东县| 丹巴县| 施秉县| 安陆市| 青铜峡市| 屏东县| 博兴县| 鹤山市| 读书| 河北区| 琼海市| 印江| 华蓥市| 西林县| 开阳县| 霍山县| 江北区| 新兴县| 政和县| 洞头县| 白银市| 唐山市| 隆安县| 铁岭市| 屯昌县| 墨竹工卡县| 吉林市| 楚雄市|