ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • List<MultipartFile> 가 톰캣서버,스프링에서 읽어드리는 과정
    Spring 2024. 11. 12. 22:52
    728x90
    반응형

    1. 클라이언트와 서버의 연결 및 요청 전송

    클라이언트가 500MB 비디오 파일을 서버에 업로드할 때, 보통 HTTP POST 요청을 통해 파일 데이터를 전송합니다. 이 과정에서 클라이언트와 서버 간에 TCP 연결이 설정됩니다.

    1. TCP 연결 수립 (3-way handshake):
      • 클라이언트와 서버는 서로 TCP 연결을 설정하기 위해 3-way handshake를 수행합니다.
      • 이 과정에서 클라이언트는 서버에 SYN 패킷을 보내고, 서버는 ACK 패킷으로 응답하여 연결이 설정됩니다.
    2. HTTP POST 요청 시작:
      • 연결이 설정된 후, 클라이언트는 HTTP POST 요청의 헤더를 먼저 전송합니다. 헤더에는 파일의 메타데이터(예: 파일명, 크기, MIME 타입 등)가 포함됩니다.
      • 서버는 클라이언트의 헤더 정보를 읽고, 그다음에 전송될 파일 데이터를 준비합니다.

    2. 파일 데이터 전송 및 서버의 처리 준비

    파일 데이터 전송은 청크 전송(Chunked Transfer Encoding) 방식으로 이루어집니다. 파일은 청크로 나뉘어 네트워크를 통해 스트리밍됩니다.

    1. 클라이언트 측 데이터 청크화:
      • 클라이언트는 파일을 일정 크기의 청크로 나눠서 전송합니다. 각 청크는 TCP 패킷으로 분할되어 네트워크를 통해 서버로 전송됩니다.
      • 예를 들어, 500MB 파일이 64KB 청크로 나뉘어 각각 네트워크를 통해 전송될 수 있습니다.
    2. 서버 측 데이터 수신 및 임시 저장:
      • 서버는 네트워크 소켓을 통해 데이터를 수신하고, InputStream으로 이를 읽어들입니다.
      • 대부분의 웹 서버는 업로드된 파일을 서버의 임시 디렉터리에 일시적으로 저장합니다. 예를 들어, Tomcat 서버는 기본적으로 /tmp 디렉터리 같은 위치에 임시 파일을 저장해 두고, 이후 처리가 끝나면 삭제합니다.
      • 파일이 임시 저장되는 동안, 서버는 InputStream을 사용하여 이 파일에 접근할 수 있습니다.

    임시 저장 위치: 임시 디렉터리 위치는 서버 설정에 따라 다릅니다. 대부분의 Java 웹 애플리케이션 서버(Tomcat, Jetty 등)는 java.io.tmpdir 시스템 속성에 정의된 디렉터리에 임시 파일을 저장합니다. 이 위치는 서버 설정을 통해 변경할 수 있습니다.


    3. 서버 측에서 InputStream을 통한 데이터 처리

    서버는 InputStream을 사용하여 클라이언트가 업로드한 파일을 처리합니다. 이 과정에서 스트리밍 방식으로 파일을 읽기 때문에 메모리 효율적입니다.

    1. InputStream을 통한 청크 단위 파일 처리:
      • 서버는 InputStream.read() 메서드를 호출하여 청크 단위로 데이터를 읽습니다. 각 청크는 내부 버퍼에 적재되고, 필요한 만큼 메모리에 적재된 후 바로 처리됩니다.
      • 예를 들어, BufferedInputStream을 사용하면 내부적으로 8KB 또는 그 이상의 버퍼로 청크를 읽으며, 네이티브 운영체제 파일 API와 상호작용합니다.
    2. 서버의 네이티브 코드 작업 (Java의 경우):
      • Java에서는 InputStream이 네이티브 파일 시스템 API와 상호작용합니다. 일반적으로 운영 체제의 네이티브 파일 입출력 라이브러리를 호출하여, 데이터가 OS 파일 캐시를 통해 메모리에 로드되고 필요할 때마다 Java 애플리케이션에 전달됩니다.
      • 운영 체제 수준에서 파일 데이터를 스트리밍하는 방식으로 처리하여 메모리 사용량을 최소화합니다.
    3. 네트워크 계층의 역할:
      • 네트워크 계층에서는 TCP 연결을 통해 파일 청크를 재조립하여, 각 청크가 서버의 InputStream으로 연속적으로 전달됩니다.
      • 데이터는 TCP 버퍼를 통해 이동하며, 서버는 네트워크 버퍼의 데이터를 스트리밍 방식으로 받아와 InputStream을 통해 읽습니다.

     

     

    1gb가 서버에 /tmp에 저장된뒤 컨트롤러에서 받게될댄 MultipartFile객체가 만들어진다고하면, 요청이 늦을수도있네? 예를들어 내가 10시 10분 10초에 보냈으면 서버에선 비디오 파일이 늦게 저장될경우엔 10분 15초에 응답을 받을수있으니, 로그엔 15초로 찍힐수도있겠네?

     

    네, 정확하게 이해하셨습니다! 대용량 파일이 업로드될 때는 서버가 클라이언트의 요청을 받는 시점과, 컨트롤러에서 MultipartFile 객체로 해당 파일을 실제로 처리할 수 있는 시점 사이에 지연이 발생할 수 있습니다. 이 과정에서 발생하는 지연은 다음과 같은 이유로 발생할 수 있습니다:

    1. 파일 데이터 수신 시간: 클라이언트가 1GB의 파일을 업로드할 때, 네트워크 속도에 따라 파일이 서버에 도착하는 데 시간이 걸립니다. 서버가 HTTP 요청을 받았더라도, 파일 데이터가 모두 수신될 때까지는 요청 처리가 완료되지 않은 상태로 남아있게 됩니다.
    2. 임시 파일 저장 시간: 서버는 파일 데이터가 모두 수신되면, 이를 /tmp 디렉토리에 임시 파일로 저장합니다. 대용량 파일일수록 이 저장 과정에서 시간이 더 걸릴 수 있습니다.
    3. 컨트롤러 호출 지연: 모든 파일이 임시 파일로 저장된 후에야 MultipartFile 객체가 생성되고, 이 시점에 비로소 컨트롤러 메서드가 호출됩니다. 따라서 파일 업로드가 끝난 후 컨트롤러로 요청이 전달되는 데까지 추가적인 지연이 발생할 수 있습니다.

    실제 로그 타임 스탬프 예시

    예를 들어, 클라이언트가 10시 10분 10초에 1GB 파일을 업로드 요청했더라도, 다음과 같은 흐름으로 지연이 발생할 수 있습니다:

    1. 10시 10분 10초 - 클라이언트가 업로드 요청을 보냄.
    2. 10시 10분 12초 - 서버가 HTTP 요청을 수신하고, 파일 데이터 수신 시작.
    3. 10시 10분 15초 - 파일 데이터 수신이 완료되고 /tmp에 임시 파일로 저장 완료.
    4. 10시 10분 15초 - MultipartFile 객체가 생성되고, 컨트롤러 메서드 호출.

    이 예시에서 클라이언트가 10시 10분 10초에 요청을 보냈지만, 서버의 로그에는 컨트롤러가 호출된 시점인 10시 10분 15초가 기록될 수 있습니다.

    따라서, 대용량 파일 업로드 시 컨트롤러가 호출되기까지의 지연 시간은 네트워크 속도와 서버의 파일 저장 속도에 따라 달라질 수 있으며, 요청의 시작 시점과 컨트롤러에서 실제로 처리하는 시점 간에 시간 차이가 생길 수 있습니다.


    해결 방안 (필요할 경우)

    만약 이런 지연을 줄이거나 더 정확한 요청 시작 시간을 기록하고 싶다면:

    1. 미리 요청의 시작 시간을 기록: 필터나 인터셉터를 사용해 HTTP 요청이 수신된 즉시 시작 시간을 기록할 수 있습니다.
    2. 비동기 방식으로 업로드 처리: 업로드 완료를 기다리지 않고 바로 응답을 반환한 후 백그라운드에서 파일 저장 및 처리를 진행하는 비동기 방식을 고려할 수도 있습니다.

    하지만 대부분의 경우, 업로드가 완료되기 전까지는 컨트롤러가 호출되지 않는 구조가 일반적이므로, 대용량 파일 업로드의 경우 어느 정도의 지연은 감안해야 합니다.

    728x90
    반응형
Designed by Tistory.