InfoGrab DocsInfoGrab Docs

이미지 스케일링 가이드

요약

이 섹션은 GitLab 이미지 스케일러와 그 사용 방법에 대한 간략한 개요를 담고 있습니다. GitLab의 이미지 스케일링 역사에 대한 일반적인 소개는 이 Unfiltered 블로그 포스트를 참고하세요. 버전 13.6부터 GitLab은 페이지 데이터 용량을 줄이기 위해 요청 시 이미지를 축소합니다.

이 섹션은 GitLab 이미지 스케일러와 그 사용 방법에 대한 간략한 개요를 담고 있습니다.

GitLab의 이미지 스케일링 역사에 대한 일반적인 소개는 이 Unfiltered 블로그 포스트를 참고하세요.

왜 이미지 스케일링인가?#

버전 13.6부터 GitLab은 페이지 데이터 용량을 줄이기 위해 요청 시 이미지를 축소합니다. 이는 "네트워크 전송 데이터"의 양을 줄일 뿐만 아니라, 브라우저가 처리해야 할 작업이 줄어들기 때문에 렌더링 성능 향상에도 도움이 됩니다.

언제 이미지를 스케일링하는가?#

일반적으로 이미지 스케일러는 클라이언트가 쿼리 스트링에 width 파라미터를 추가하여 이미지 리소스를 요청할 때 트리거됩니다. 그러나 특정 종류 및 포맷의 이미지만 스케일링합니다. 이미지를 리스케일 허용할지 여부는 하드코딩된 규칙과 구성 설정의 조합으로 결정됩니다.

하드코딩된 규칙은 다음만 허용합니다:

또한 Workhorse의 구성으로 인해 다음 경우 이미지 스케일러가 요청을 거부할 수 있습니다:

  • 이미지 파일이 너무 큰 경우 (max_filesize로 제어, 설정된 크기(바이트)를 초과하지 않는 이미지만 리스케일합니다. max_filesize 참조).

  • 이미 너무 많은 이미지 스케일러가 실행 중인 경우 (max_scaler_procs로 제어).

예를 들어, 다음은 GitLab 프로젝트 아바타를 원본 크기와 64픽셀로 축소한 크기로 각각 제공하는 두 가지 URL입니다. 두 번째 요청만 이미지 스케일러를 트리거합니다:

어디서 이미지를 스케일링하는가?#

Rails와 Workhorse는 현재 이미지 리스케일을 위해 협력합니다. 이는 GitLab의 일반적인 구현 및 성능 패턴입니다: 요청 인증 및 유효성 검사와 같은 중요한 비즈니스 로직은 Rails에서 처리하고, "무거운 작업"인 스케일링 및 바이너리 데이터 제공은 Workhorse에서 처리합니다.

전체 요청 흐름은 다음과 같습니다:

sequenceDiagram Client->>+Workhorse: GET /uploads/-/system/project/avatar/278964/logo-extra-whitespace.png?width=64 Workhorse->>+Rails: forward request Rails->>+Rails: validate request Rails->>+Rails: resolve image location Rails-->>-Workhorse: Gitlab-Workhorse-Send-Data: send-scaled-image Workhorse->>+Workhorse: invoke image scaler Workhorse-->>-Client: 200 OK

Rails#

현재 이미지 스케일링은 위에서 언급된 아바타와 같이 Upload 엔티티로 제한됩니다. 따라서 Rails의 모든 이미지 스케일링 관련 로직은 현재 send_file_upload 컨트롤러 믹스인에서 찾을 수 있습니다. Workhorse를 통해 클라이언트로부터 요청을 받으면, 위에서 언급한 기준에 따라 이미지 스케일러를 트리거해야 하는지 확인합니다. 트리거해야 하는 경우, Workhorse가 스케일링 요청을 수행하는 데 필요한 파라미터와 함께 특수 응답 헤더 필드 (Gitlab-Workhorse-Send-Data)를 렌더링합니다. Rails가 요청이 유효한 이미지 스케일링 요청이 아니라고 판단하면, 일반 업로드를 제공하는 경로를 따릅니다.

Workhorse#

Rails가 요청을 유효하다고 판단한 경우, Workhorse가 처리를 이어받습니다. Rails 응답을 통해 send-scaled-image 명령을 받으면, 이미지를 리스케일하는 방법을 알고 있는 특수 응답 인젝터가 호출됩니다. 이 인젝터에 필요한 입력은 이미지의 위치 (이미지가 블록 스토리지에 있는 경우 경로, 그렇지 않으면 원격 스토리지 URL)와 원하는 너비뿐입니다. Workhorse는 위치를 투명하게 처리하므로 Rails는 이미지가 실제로 어디에 있는지 신경 쓸 필요가 없습니다.

또한 Rails에서의 요청 유효성 검사에 더해, Workhorse는 실제로 이미지를 리스케일할 수 있는지 확인하기 위해 여러 사전 조건 검사를 실행합니다. 예를 들어 스케일러 프로세스 예산을 초과하지 않는지, 파일이 메모리 소비를 적절히 유지하기 위한 설정된 최대 허용 크기 제약을 충족하는지 등을 확인합니다.

실제 이미지 스케일링을 위해 Workhorse는 최종적으로 실제 스케일링 작업을 수행하는 자식 프로세스로 포크(fork)하고, 결과를 클라이언트에 스트리밍합니다.

리스케일된 이미지 캐싱#

현재 리스케일된 이미지는 어디에도 저장하지 않습니다. 더 작은 버전이 요청될 때마다 스케일러가 실행됩니다. 그러나 Workhorse는 클라이언트 캐시의 이미지가 최신인 경우 스케일러를 건너뛸 수 있도록 하는 표준 조건부 HTTP 요청 전략을 구현합니다. 이를 위해 원본 이미지 파일의 UTC 타임스탬프를 담은 Last-Modified 헤더 필드를 전송하고, 클라이언트 요청의 If-Modified-Since 헤더 필드와 대조합니다. 원본 이미지가 변경되어 리스케일링이 필요한 경우에만 스케일러를 다시 실행합니다.

이미지 스케일링 가이드

GitLab v19.1
원문 보기
요약

이 섹션은 GitLab 이미지 스케일러와 그 사용 방법에 대한 간략한 개요를 담고 있습니다. GitLab의 이미지 스케일링 역사에 대한 일반적인 소개는 이 Unfiltered 블로그 포스트를 참고하세요. 버전 13.6부터 GitLab은 페이지 데이터 용량을 줄이기 위해 요청 시 이미지를 축소합니다.

이 섹션은 GitLab 이미지 스케일러와 그 사용 방법에 대한 간략한 개요를 담고 있습니다.

GitLab의 이미지 스케일링 역사에 대한 일반적인 소개는 이 Unfiltered 블로그 포스트를 참고하세요.

왜 이미지 스케일링인가?#

버전 13.6부터 GitLab은 페이지 데이터 용량을 줄이기 위해 요청 시 이미지를 축소합니다. 이는 "네트워크 전송 데이터"의 양을 줄일 뿐만 아니라, 브라우저가 처리해야 할 작업이 줄어들기 때문에 렌더링 성능 향상에도 도움이 됩니다.

언제 이미지를 스케일링하는가?#

일반적으로 이미지 스케일러는 클라이언트가 쿼리 스트링에 width 파라미터를 추가하여 이미지 리소스를 요청할 때 트리거됩니다. 그러나 특정 종류 및 포맷의 이미지만 스케일링합니다. 이미지를 리스케일 허용할지 여부는 하드코딩된 규칙과 구성 설정의 조합으로 결정됩니다.

하드코딩된 규칙은 다음만 허용합니다:

또한 Workhorse의 구성으로 인해 다음 경우 이미지 스케일러가 요청을 거부할 수 있습니다:

  • 이미지 파일이 너무 큰 경우 (max_filesize로 제어, 설정된 크기(바이트)를 초과하지 않는 이미지만 리스케일합니다. max_filesize 참조).

  • 이미 너무 많은 이미지 스케일러가 실행 중인 경우 (max_scaler_procs로 제어).

예를 들어, 다음은 GitLab 프로젝트 아바타를 원본 크기와 64픽셀로 축소한 크기로 각각 제공하는 두 가지 URL입니다. 두 번째 요청만 이미지 스케일러를 트리거합니다:

어디서 이미지를 스케일링하는가?#

Rails와 Workhorse는 현재 이미지 리스케일을 위해 협력합니다. 이는 GitLab의 일반적인 구현 및 성능 패턴입니다: 요청 인증 및 유효성 검사와 같은 중요한 비즈니스 로직은 Rails에서 처리하고, "무거운 작업"인 스케일링 및 바이너리 데이터 제공은 Workhorse에서 처리합니다.

전체 요청 흐름은 다음과 같습니다:

sequenceDiagram Client->>+Workhorse: GET /uploads/-/system/project/avatar/278964/logo-extra-whitespace.png?width=64 Workhorse->>+Rails: forward request Rails->>+Rails: validate request Rails->>+Rails: resolve image location Rails-->>-Workhorse: Gitlab-Workhorse-Send-Data: send-scaled-image Workhorse->>+Workhorse: invoke image scaler Workhorse-->>-Client: 200 OK

Rails#

현재 이미지 스케일링은 위에서 언급된 아바타와 같이 Upload 엔티티로 제한됩니다. 따라서 Rails의 모든 이미지 스케일링 관련 로직은 현재 send_file_upload 컨트롤러 믹스인에서 찾을 수 있습니다. Workhorse를 통해 클라이언트로부터 요청을 받으면, 위에서 언급한 기준에 따라 이미지 스케일러를 트리거해야 하는지 확인합니다. 트리거해야 하는 경우, Workhorse가 스케일링 요청을 수행하는 데 필요한 파라미터와 함께 특수 응답 헤더 필드 (Gitlab-Workhorse-Send-Data)를 렌더링합니다. Rails가 요청이 유효한 이미지 스케일링 요청이 아니라고 판단하면, 일반 업로드를 제공하는 경로를 따릅니다.

Workhorse#

Rails가 요청을 유효하다고 판단한 경우, Workhorse가 처리를 이어받습니다. Rails 응답을 통해 send-scaled-image 명령을 받으면, 이미지를 리스케일하는 방법을 알고 있는 특수 응답 인젝터가 호출됩니다. 이 인젝터에 필요한 입력은 이미지의 위치 (이미지가 블록 스토리지에 있는 경우 경로, 그렇지 않으면 원격 스토리지 URL)와 원하는 너비뿐입니다. Workhorse는 위치를 투명하게 처리하므로 Rails는 이미지가 실제로 어디에 있는지 신경 쓸 필요가 없습니다.

또한 Rails에서의 요청 유효성 검사에 더해, Workhorse는 실제로 이미지를 리스케일할 수 있는지 확인하기 위해 여러 사전 조건 검사를 실행합니다. 예를 들어 스케일러 프로세스 예산을 초과하지 않는지, 파일이 메모리 소비를 적절히 유지하기 위한 설정된 최대 허용 크기 제약을 충족하는지 등을 확인합니다.

실제 이미지 스케일링을 위해 Workhorse는 최종적으로 실제 스케일링 작업을 수행하는 자식 프로세스로 포크(fork)하고, 결과를 클라이언트에 스트리밍합니다.

리스케일된 이미지 캐싱#

현재 리스케일된 이미지는 어디에도 저장하지 않습니다. 더 작은 버전이 요청될 때마다 스케일러가 실행됩니다. 그러나 Workhorse는 클라이언트 캐시의 이미지가 최신인 경우 스케일러를 건너뛸 수 있도록 하는 표준 조건부 HTTP 요청 전략을 구현합니다. 이를 위해 원본 이미지 파일의 UTC 타임스탬프를 담은 Last-Modified 헤더 필드를 전송하고, 클라이언트 요청의 If-Modified-Since 헤더 필드와 대조합니다. 원본 이미지가 변경되어 리스케일링이 필요한 경우에만 스케일러를 다시 실행합니다.