이미지 스케일링 가이드

이 섹션에는 GitLab 이미지 스케일러의 간단한 개요와 작업 방법이 포함되어 있습니다.

일반적으로 이미지 스케일링에 대한 GitLab의 역사에 대한 개요는 이 Unfiltered 블로그 포스트를 참고하실 수 있습니다.

이미지 스케일링의 필요성

13.6 버전부터 GitLab은 페이지 데이터 크기를 줄이기 위해 이미지를 요청 시 축소합니다. 이로써 “와이어 상의” 데이터 양이 줄어들 뿐만 아니라 브라우저가 처리해야 할 작업도 줄어듭니다.

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

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

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

또한, Workhorse의 구성에서 이미지 스케일러가 요청을 거부하도록 설정되어 있을 수 있습니다:

  • 이미지 파일이 너무 큰 경우 (max_filesize로 제어됨 - 바이트로 구성된 크기를 초과하지 않는 이미지만 다시 조정합니다(자세한 내용은 max_filesize 참조)).
  • 이미지 스케일러가 이미 너무 많이 실행 중인 경우 (max_scaler_procs로 제어됨)(https://gitlab.com/gitlab-org/gitlab/-/blob/master/workhorse/config.toml.example#L21)).

예를 들어, 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 컨트롤러 mixin에서 찾을 수 있습니다. 클라이언트를 통해 Workhorse를 통해 온 요청을 받으면, 위에서 언급한 기준에 따라 이미지 스케일러를 트리거해야 하는지 확인하고, 그렇다면 Workhorse가 축소 요청을 처리할 수 있도록 필요한 매개변수를 갖는 특수한 응답 헤더 필드(Gitlab-Workhorse-Send-Data)를 렌더링합니다. Rails가 요청이 유효한 이미지 스케일링 요청이 아니라고 결정하면 우리는 보통의 업로드를 제공하는 경로를 따릅니다.

Workhorse

Rails가 요청을 유효하다고 판단하면 Workhorse가 인수합니다. Rails 응답을 통해 send-scaled-image 명령을 받으면 이미지 스케일링을 알 수 있는 특별한 응답 주입기 가 호출됩니다. 이 응답 주입기는 이미지를 축소하는 방법을 알고 있습니다. 필요한 입력은 이미지의 위치(이미지가 블록 리포지터리에 있는 경우 경로 또는 원격 리포지터리 URL인 경우)와 원하는 폭입니다. Workhorse는 이미지가 실제로 있는 위치를 Rails가 걱정할 필요 없이 투명하게 처리합니다.

또한, Rails의 요청 유효성 검사에서 Workhorse는 스케일러 프로세스 예산을 초과하지 않도록하고 메모리 소비를 확인한다는 여러 전제 조건 검사를 실행합니다. 파일이 구성된 최대 허용 크기 제약조건을 충족하는지도 확인합니다.

실제 이미지를 축소하기 위해, Workhorse는 실제 축소 작업을 수행하는 자식 프로세스로 분기하고 결과를 클라이언트에게 다시 스트리밍합니다.

축소된 이미지 캐싱

우리는 현재 축소된 이미지를 어디에 저장하지 않습니다. 스케일러는 작은 버전이 요청될 때마다 실행됩니다. 그러나 Workhorse는 조건부 HTTP 요청 전략을 구현하여 클라이언트 캐시에 이미지가 최신 상태인 경우 스케일러를 건너뛸 수 있습니다. 따라서 우리는 클라이언트 요청의 Last-Modified 헤더 필드에 원본 이미지 파일의 UTC 타임스탬프를 전송하여 일치하는 경우 스케일러를 다시 실행할 필요가 없게 합니다.