이미지 스케일링 가이드
이 섹션에는 GitLab 이미지 스케일러의 간단한 개요와 해당 작업 방법이 포함되어 있습니다.
GitLab에서 이미지 스케일링의 역사에 대한 일반적인 소개는 아마도 이 Unfiltered 블로그 게시물에 관심이 있을 것입니다.
이미지 스케일링의 목적
버전 13.6부터 GitLab은 페이지 데이터 풋프린트를 줄이기 위해 이미지를 요청에 따라 축소합니다. 이로써 “와이어 상의” 데이터 양을 줄이는 동시에 브라우저가 처리해야 하는 작업을 줄여 렌더링 성능에도 도움을 줍니다.
언제 이미지를 스케일하나요?
일반적으로 이미지 스케일러는 클라이언트가 쿼리 문자열에 width
매개변수를 추가하여 이미지 자원을 요청할 때 트리거됩니다. 그러나 특정 유형과 형식의 이미지만 스케일링합니다.
이미지를 스케일링할지 여부는 하드코딩된 규칙과 구성 설정의 조합에 의해 결정됩니다.
하드코딩된 규칙은 다음만 허용합니다:
또한 Workhorse의 구성에서는:
- 이미지 파일이 너무 큰 경우 (구성된 바이트 크기를 초과하지 않는 이미지만 축소,
max_filesize
참조) - 이미지 스케일러가 이미 실행 중인 경우 (
max_scaler_procs
에 의해 제어됨,max_scaler_procs
참조)
이중 어느 것에 해당되면 이미지 스케일러가 요청을 거부합니다.
예를 들어, GitLab 프로젝트 아바타를 원본 크기 및 64픽셀로 축소한 두 가지 다른 URL은 다음과 같습니다. 두 번째 요청에서만 이미지 스케일러가 트리거됩니다:
https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/source/images/gitlab-logo-extra-whitespace.png
https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/source/images/gitlab-logo-extra-whitespace.png?width=64
이미지 스케일링 위치
현재 Rails와 Workhorse가 이미지를 다시 조정하도록 협력합니다. 이는 GitLab에서 일반적인 구현 및 성능 패턴입니다: 강력한 비즈니스 로직(예: 요청 인증 및 유효성 검사)은 Rails에서 이루어지고, “중요한 작업”인 스케일링 및 이진 데이터 제공은 Workhorse에서 처리됩니다.
전체 요청 흐름은 다음과 같습니다:
Rails
현재 이미지 스케일링은 Upload
엔터티에만 적용되며, 특히 위에서 언급한 아바타만 해당됩니다.
따라서, Rails에서 이미지 스케일링 관련 로직은 현재
send_file_upload
컨트롤러 mixin에서 찾을 수 있습니다. 클라이언트를 통해 Workhorse를 통해 수신된 요청을 받으면, 우리는 상기 기준에 따라 이미지 스케일러를 트리거해야 하는지 확인하고, 그렇게 결정되면 Workhorse가 스케일링 요청을 처리하기 위해 필요한 매개변수가 포함된 특수 응답 헤더 필드 (Gitlab-Workhorse-Send-Data
)를 렌더링합니다. 만약 Rails이 요청이 유효한 이미지 스케일링 요청으로 판단하지 않는다면, 보통의 업로드를 제공하는 방식과 동일한 경로를 따릅니다.
Workhorse
만일 Rails에서 요청이 유효하다고 판단되면 Workhorse가 이를 처리합니다. Rails 응답을 통해 send-scaled-image
지시를 받으면, 이미지를 리스케일하는 방법을 알고 있는 특수 응답 주입기
가 호출됩니다. 그에 필요한 유일한 입력은 이미지의 위치(이미지가 블록 스토리지에 있는 경우 경로 또는 원격 스토리지의 URL)와 원하는 너비입니다. Workhorse가 위치를 투명하게 처리하여 Rails가 이미지가 실제로 있는 위치에 대해 걱정할 필요가 없습니다.
또한, Rails의 요청 유효성 검사와 마찬가지로, Workhorse는 필요한 스케일러 프로세스 예산을 초과하지 않는지 및 구성된 최대 허용 크기 제약을 충족하는지 확인하는 여러 사전 조건 검사를 수행합니다(메모리 사용량을 낮추기 위해).
실제로 이미지를 스케일하는 경우, Workhorse는 실제 스케일링 작업을 수행하는 자식 프로세스로 분기하고 결과를 클라이언트에게 다시 스트리밍합니다.
리스케일된 이미지 캐싱
현재 리스케일된 이미지를 어디에도 저장하지 않습니다. 따라서 작은 크기의 이미지가 요청될 때마다 스케일러가 실행됩니다.
그러나 Workhorse는 클라이언트 캐시의 이미지가 최신 상태인지 확인하는 표준 조건부 HTTP 요청 전략을 구현합니다.
이를 위해 클라이언트 요청의 If-Modified-Since
헤더 필드와 원본 이미지 파일의 UTC 타임스탬프를 담은 Last-Modified
헤더 필드를 비교합니다. 원본 이미지가 변경되고 리스케일이 필요한 경우에만 스케일러를 다시 실행합니다.