효자손개발자
581
2017-11-17 09:30:21
9
11270

대용량(2GB 이상) 파일 업로드 관련 질문입니다


안녕하세요 신입 개발자입니다


얼마전까지 회사에서 하는 서비스에서 파일업로드 서비스를 구현하는데

외부 컴포넌트를 따로 구매하여 서비스를 하곤 했습니다.

그런데 그 서비스는 2기가 이상의 대용량을 구현하려면 추가로 서비스 비용을 지불해야하는 불편함이 있어서, 저에게 파일업로드를 구현해보도록 요청하셨는데요


서버는 톰캣8.5환경이고, 스프링에서 제공하는  MultipartResolver 라는 객체를 사용하여

Max upload size를 5기가 정도로 잡아주고 로컬에서 테스트하니까 크롬, IE 에서 문제없이 업로드가 되는 것으로 보입니다


제가 뭘 빼뜨린 부분이 있는건지

생각보다 쉽게, 별 문제없이 작동하는 것 같은데

혹시 서비스함에 있어서 문제가 발생할 수 있는 여지가 있을까요?


생각보다 간단히(?) 처리될 수 있는 것을 그동안 외부 컴포넌트를 결제하여 사용했을까...

뭔가 이유가 있지 않을까 의구심이 드네요

0
  • 답변 9

  • 구구구구우
    1k
    2017-11-17 09:55:10

    일반적인 방식으로 서블릿에 요청 처리를 구현했다면

    긴시간을 요구한 파일 전송 요청이 제한된 스레드자원을 모두 소모해서 많은 사용자들이 파일전송 뿐만 아니라 다른 서비스도 진행을 할수 없겠죠.

    즉 파일전송의 경우, 파일전송을 처리하는 쓰레드 풀에서 작업을 진행수 있도록 해야하구요, 이말은 파일전송을 처리하는 자원(스레드)이 다른 서비스 사용자들을 방해하지 않도록 할당되도록 해야한다는겁니다.






  • 잇힝힝
    54
    2017-11-17 09:57:50

    괜찮은 플러그인이라면 파일전송실패시의 대비책, 다중사용자가 대용량파일을 동시에 업로드했을때 방안등등이 들어가있을겁니다.


    고로 문의해보시는게 빠르실것 같습니다.

    2기가 이상 등록시 어떤기능들이 더 추가되는지에 대해서요.

  • 효자손개발자
    581
    2017-11-17 10:07:44

    답변감사합니다.

    구구구구우 파일 전송시 쓰레드를 따로 할당하여 전송하도록 하면 된다는 말씀이신가요??

    다행히 저희 서비스가 CMS서비스로 따로 분리되어

    파일업로드하는 서버에는 많은 사용자가 몰리진 않을 것 같은데

    말씀하신 방향으로 좀 더 조사해봐야겠네요

    답변 너무 감사드립니다!

  • 효자손개발자
    581
    2017-11-17 10:08:36

    잇힝힝 이전에 사용했던 컴포넌트를 거두는 것이 목적이라 제 선에서 해결할 방법을 더 찾아봐야겠네요ㅠㅠ

    다중 사용자에 대한 처리 등 생각치 못했는데 조사를 좀 더 해봐야겠네요 감사합니다!!

  • 구구구구우
    1k
    2017-11-17 10:22:39

    스레드를 따로 할당한다던지 스레드풀을 따로 둔다든지 하는것들은 어떠한 전략적인 의미에서 이야기하는것들이고, 제가 하고자 하는 얘기는 파일전송 요청 자체가 다른 서비스들과 자원(메모리적으로)을 공유하게 되었을때 문제가 된다는 이야기에요

    파일전송을 담당하는 서버가 따로 있다면 제가 이야기한 부분에서는 문제가 되지 않을거 같은데요. 

    그리고 저는 원론적인 측면에서만 이야기를 한거라서 실제 구현상에서 어떤지는 잘몰라요

  • 효자손개발자
    581
    2017-11-17 10:45:02

    구구구구우 자꾸 질문드려 죄송합니다

    기본 지식이 부족하여 서버간 통신에서 이해가 안되는 부분이 있어서요ㅜㅜ

    일반적으로 IIS와 Apache/Tomcat에서의 HTTP 요청 크기는 최대 2GB로 제한되어 있으며 실질적으로는 웹 서버의 HTTP 요청 제한 설정 또는 웹 방화벽에 의해 더 작은 크기로 제한되어 있습니다.

    문제가 있을까 싶어서 더 찾아보니 이런 제한이 있는 것으로 보입니다


    그런데 궁금한것이 파일 전송을 할때, 예를들어 10MB 파일이나 3GB 파일이나 다를 것 없이

    파일을 업로드하는 순간 이 파일 메타정보를 쪼개어 패킷(?) 단위로 서버에 전송해서 파일을 쌓아가는 구조가 아닌가요?

    만약 이렇게 파일이 전송된다면, 말씀하신대로 이 파일의 전송이 완료되기 까지 서버에 부하가 생겨 다른 사용자들에게 문제를 줄 수 있을 것이라 이해되는데요


    방화벽 자체에서 이 파일이 한번에 3GB가 넘어오는 것이 아니기 때문에

    어떻게 방화벽이 이 파일이 2GB 이상인 것을 체크하여 요청을 차단할 수 있을까요?


    서버에서 파일 전송 요청을 받아주고 있다가 2GB가 체크되면 그 순간 서버에서 차단해버리는 걸까요?



  • 타키투스
    882
    2017-11-18 14:22:19

    파일 전송할때에 http body length 값을 함께 보냅니다. http 프로토콜은 아주 단순한데 파일 전송시에 파일 내용은 http body 에 포함되 전송됩니다. 단, http body 길이는 정해져 있어서 data/multipart 를 줘야 웹서버가 받아서 하나로 합치는 작업을 수행하죠. 전체 파일 길이를 알아야 조립할때 맞게 조립하는 거죠.

    그래서 웹 서버에서는 post 시 http body 크기를 조절할 수 있는 설정값이 다 존재 합니다. 


    그리고 파일 업로드 처리를 was 로 하는건 비추 입니다. 


  • 효자손개발자
    581
    2017-11-18 16:32:18

    타키투스 마침 공부하려 노트북을 열었는데 좋은 답변이 있어서 너무 감사드립니다

    파일전송시 타입을 data/multipart 로 전송하고, 그 전송한 데이터의 http body length 값을 체크하여 데이터의 크기를 가늠할 수 있다는 말씀이실까요?


    아파치/톰캣의 버전이 올라가며 변경된 것인지 지금 3기가 이상의 파일을 테스트 중인데 문제없이 업로드가 되는 것으로 보이네요..

    그런데 업로드 처리를 톰캣으로하지 않는다면 어떻게 구현할 수 있는거죠...?

  • 타키투스
    882
    2017-11-19 22:59:29

    이게 아키 문제이기도 하고 방법에 문제이기도 해서 딱히 제 말이 맞다는건 아닙니다만, 

    전반적으로 static 파일 같은건 was 에서 처리를 안하려고 합니다. java 로직 처리하기도 바쁜데 전적파일까지 서비스 할려면 힘드니까요.


    그래서 웹서버를 두고 정적파일을 서비스하게 되는데, 문제는 정적파일을 업로드하게 될때죠. 업로드 로직은 was 에 있고 서비스는 웹서버에서 해야하니까... 그래서 이럴때 업로드만 처리하는 조그마한 서버를 제작하기도 합니다. node.js, python 같은 걸 웹 서버에 설치하고 업로드만 처리하는 마이크로 웹서버만 올려 놓는 거죠. 


    보통 업로드 접속이 대량으로 발생하진 않고 오직 업로드만 처리하면 되기 때문에 잡고 가볍지만 제대로 처리할 목적으로 별도로 구축하곤 합니다. 


    was 서버를 이용해서 업로드를 하게되면 불필요한 자원소모로 인해서 성능이 떨어집니다. 3GB 를 was 가 받는동안 지속적으로 Disk I/O 가 발생할 거고 대역폭도 잡아먹을거고 자바쓰레드는 지속적으로 cpu 를 잡아먹을거고... 동접처리하기 바빠죽겠는데 저런거까지 해야하나... 싶은거죠..


    aws 를 이용할 경우 업로드를 람다로 구현하고 저장을 S3에 한다음에 서비스를 S3로 하는 경우도 있습니다.

  • 로그인을 하시면 답변을 등록할 수 있습니다.