-
[ASP.NET Core] 개선된 다운로드 예제(feat. ASP.NET을 쓰지 말아야할 이유 1 Stack 추가).NET/ASP.NET Core 2021. 4. 15. 23:02반응형
예전에 ASP.NET Core로 일반적인 파일 다운로드 기능 구현 예제를 만든적이 있었다. (ddochea.tistory.com/76)
해당 예제에선 파일을 다운로드할 때 byte[] 버퍼에 담아 전달하도록 작성했었는데, 그 이유는 크기가 큰 파일을 전달할때 생기는 메모리 사용 문제점, 그리고 이를 해결하기위한 스트리밍 방법인 "HTTP range requests" 예제를 구현하고 비교하는 포스트를 작성하기 위한 일종의 큰 그림(?) 이었다.
"HTTP range requests"에 관한 정보는 아래 링크에서 확인할 수 있다.
developer.mozilla.org/ko/docs/Web/HTTP/Range_requests
간단히 말해 미디어 파일이나 크기가 큰 파일들을 한꺼번에 전달하는 것이 아닌, Accept-Ranges 헤더와 상태코드 "206 partial content" 를 통해 분할전달하는 HTTP 웹 기술을 뜻한다. 서버에 따라 지원여부가 갈릴 수도 있는데, HTTP/3 까지 구현되어가는 와중에 이게 안되는 서버 시스템을 쓰는 일은 아마 없을 것이다.
만약 HTTP range requests 처리 없이, ddochea.tistory.com/76 의 예제에서 1GB가 넘는 파일을 다운로드하려 한다면 웹서버의 메모리사용량이 1GB를 넘어서게 된다. 1명만 다운로드 받는데 1GB라면, 10명이 동시접속해서 다운로드를 요청했을때 순간 메모리사용량이 10GB에 육박하게 될 수 있음을 의미한다.
따라서 byte[] 크기를 1MB 로 고정하고, 분할 처리하는 방법을 구현하여 "큰 파일은 이렇게 하면 된다"를 보이려고 했는데...
인터넷에서 확인해보니 ASP.NET Core는 그냥 '알아서' 처리가 된다고 한다. 정확하게는 FileStreamResult 에 EnableRangeProcessing라는 옵션이 2.1부터 생겼는데, 이 옵션추가와 함께 변경이 된 건지, 아니면 무관하게 ASP.NET Core부터 적용 된건지는 모르겠다.
* 참고로 파일다운로드는 EnableRangeProcessing 옵션과는 무관하게 메모리 폭발없이 잘된다.
아래 예제는 1GB 크기의 테스트 파일을 다운로드 받는 예제소스이다.
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; namespace BigFileDownload.Controllers { [Route("api/[controller]")] [ApiController] public class DownloadController : ControllerBase { [HttpGet] public IActionResult GetDownloadResult() { var path = Path.Join("Download", "1gb.test"); if (System.IO.File.Exists(path)) { var file = new FileStream(path: path, mode: FileMode.Open, FileAccess.Read); return new FileStreamResult(file, "application/octet-stream") { FileDownloadName = "1gb.test", EnableRangeProcessing = true }; } else { return NotFound(); } } } }
테스트 파일은 아래 링크에서 구할 수 있다.
speedtest-tor1.digitalocean.com/
기존에 byte[] buffer를 사용할 때 보다 더 간소화되었다. 우려했던 메모리 폭발(?)도 일어나지 않았다. 다만 지난시간에 다뤘던 [ResponseCache]는 적용되지 않았다.
내가 혹시 착각했나 싶어 ASP.NET으로 동일한 테스트를 진행해보았다.
이것으로 파일 다운로드 구현방법에 대해 좀더 깊이 알아보았다. 의도와는 다른 포스트를 작성하게 되었지만 기존 ASP.NET 대비 많은 부분이 개선되었음을 알게된 유익한 시간이었다.
혹시 ASP.NET을 다루고 있는 개발자라면 ASP.NET Core로 갈아타보길 바란다.
아직 주니어 개발자라면 이런거 하지말고 Spring Boot를 하기 바란다. ㅈ소기업에도 Java, python, javascript가 존재할 순 있어도, 네카라쿠배에 .NET은 없다.반응형'.NET > ASP.NET Core' 카테고리의 다른 글
[ASP.NET Core] AddController(), AddMvc(), AddControllersWithViews(), AddRazorPages() 차이점 (0) 2021.06.26 [ASP.NET Core] 세상 간편해진 Video/Audio Streaming (0) 2021.04.21 [ASP.NET Core] HTTP Cache-Control Header 를 이용한 Get 응답(Response) 캐싱 및 파일 다운로드 예제 (0) 2021.04.12 [ASP.NET Core] axios 로 Array 형식의 파라메터를 전달하는 Get 메소드 사용시 유의사항 (0) 2021.01.21 [ASP.NET Core] WebAPI 일반적인 파일업로드 기능 구현 예제 (0) 2021.01.17