이미지 스케일링 가이드

이 섹션에서는 GitLab 이미지 스케일러에 대한 간략한 개요와 이를 사용하는 방법을 설명합니다.

GitLab의 이미지 스케일링 역사에 대한 일반적인 소개를 원하신다면 이 Unfiltered 블로그 게시물에 관심이 있을 수 있습니다.

이미지 스케일링은 왜 필요할까요?

GitLab 13.6 버전부터, GitLab은 페이지 데이터 발자국을 줄이기 위해 요청에 따라 이미지를 축소합니다.
이는 “전송 중인” 데이터 양을 줄일 뿐만 아니라, 브라우저가 할 일이 줄어들기 때문에 렌더링 성능에도 도움이 됩니다.

언제 이미지를 스케일하나요?

일반적으로, 이미지 스케일러는 클라이언트가 쿼리 문자열에 width 매개변수를 추가하여 이미지 리소스를 요청할 때 트리거됩니다.
그러나 우리는 특정 종류 및 형식의 이미지만 스케일합니다.
이미지를 재조정할 수 있는지 여부는 하드코딩된 규칙과 구성 설정의 조합에 의해 결정됩니다.

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

게다가, Workhorse의 구성 때문에 다음과 같은 경우 이미지 스케일러가 요청을 거부할 수 있습니다:

  • 이미지 파일이 너무 클 경우 (controlled by max_filesize, 우리는 구성된 바이트 크기를 초과하지 않는 이미지만 재조정합니다. max_filesize를 참조하세요).
  • 너무 많은 이미지 스케일러가 이미 작동 중인 경우 (controlled by 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: 요청을 전달 Rails->>+Rails: 요청 검증 Rails->>+Rails: 이미지 위치 확인 Rails-->>-Workhorse: Gitlab-Workhorse-Send-Data: send-scaled-image Workhorse->>+Workhorse: 이미지 스케일러 호출 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는 최종적으로 실제 크기 조정 작업을 수행하는 자식 프로세스로 포크하고 결과를 클라이언트로 스트리밍합니다.

리스케일된 이미지 캐싱

현재 우리는 리스케일된 이미지를 어디에도 저장하지 않습니다; 더 작은 버전을 요청할 때마다 스케일러가 실행됩니다.

그러나 Workhorse는 클라이언트 캐시의 이미지가 최신 상태인지 확인하기 위해 스케일러를 건너뛰도록 허용하는 표준 조건부 HTTP 요청 전략을 구현합니다.

이를 위해 우리는 원래 이미지 파일의 UTC 타임스탬프를 포함한 Last-Modified 헤더 필드를 전송하고,

클라이언트 요청의 If-Modified-Since 헤더 필드와 일치시킵니다.

원본 이미지가 변경되고 리스케일이 필요해질 경우에만 스케일러를 다시 실행합니다.