首頁  >  文章  >  後端開發  >  處理 S3 檔案下載而不耗盡資源

處理 S3 檔案下載而不耗盡資源

WBOY
WBOY轉載
2024-02-10 19:36:09903瀏覽

处理 S3 文件下载而不耗尽资源

php小編新一在這裡為大家介紹一個高效的方式來處理S3檔下載,以避免耗盡伺服器資源。 S3是亞馬遜提供的可擴展的雲端儲存服務,但在處理大型檔案下載時,傳統的下載方式可能會導致伺服器資源耗盡。本文將介紹一種基於PHP的解決方案,透過分塊下載和串流的方式,有效處理S3檔案下載,提升伺服器效能和使用者體驗。讓我們一起來了解這個方法吧!

問題內容

我有一個 go-gin 應用程序,它允許在 S3 中上傳和下載多種文件類型。

上傳到 s3 之前的所有檔案均使用 AWS s3cryptoclient、AES GCM 和來自 KMS 的金鑰進行加密。因此,就 s3 儲存桶而言,一切都是二進位的。

我可以使用 getObject 的 SDK 指令將檔案下載到伺服器並解密,然後使用 io.write(tempfile) 將此檔案提供給客戶端下載。

此處的問題 S3 包含大小為 10GB 的文件,並且該伺服器每天將有多個使用者存取。正如我們所看到的,在具有 16GB RAM 的伺服器上寫入臨時檔案也會很快耗盡內存,同時我們還要注意運行此類伺服器的成本。

瓶頸是文件在獲得服務之前需要解密,在這種用例中,S3 預簽名url 就足夠了,儘管解密不是由s3 預簽名url 提供的,除非它是由客戶完成的加密,在我們的案例AWS 正在處理加密,因此解決方案不可行。

有沒有人有任何提示或可能的用例來解決這個問題,我們可以使用 go-gin/NGINX 將檔案直接寫入客戶端。

目前使用者對檔案下載的處理

s3FileStream, _ := s3c.GetBucketItem(&utils.S3ObjectBucketInput{
    Bucket: "bucketName",
    Key:    "UserFileName"
})

fileBody, err := io.ReadAll(s3FileStream.Body)
if err != nil {
    panic(err.Error())
}

fileExtension := s3FileStream.Metadata["X-Amz-Meta-Type"]

err = ioutil.WriteFile("file" + *fileExtension, fileBody, 600) // temp file
if err != nil {
    panic(err.Error())
}
c.JSON(http.StatusCreated, string(fileBody))
c.Done()

}

解決方法

一種選擇是將物件直接作為回應正文寫入客戶端:

s3FileStream, _ := s3c.GetBucketItem(&utils.S3ObjectBucketInput{
    Bucket: "bucketName",
    Key:    "UserFileName",
})
fileExtension := s3FileStream.Metadata["X-Amz-Meta-Type"]
c.DataFromReader(http.StatusCreated, 0, "application/data",
    s3FileStream.Body,
    map[string]string{"Content-Dispositon": "attachment; filename=" + "file" + *fileExtension})
c.Done()

以上是處理 S3 檔案下載而不耗盡資源的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除