ETag 캐싱으로 폴링하기

변경 사항을 계속해서 확인하기(서버에 새로운 변경 사항이 있는지 반복해서 확인하기)는 일반적으로 몇 개의 SQL 쿼리를 실행해야 하기 때문에 GitLab 인스턴스에 높은 부하를 일으킵니다. 이로 인해 GitLab.com과 같은 대규모 GitLab 인스턴스를 확장하기가 매우 어렵기 때문에 데이터베이스를 폴링하고 새로운 기능을 추가할 수 없습니다.

대신 Redis에서 ETag 캐싱과 함께 폴링 메커니즘을 사용해야 합니다.

사용 방법

  1. 폴링하려는 엔드포인트의 경로를 Gitlab::EtagCaching::Router에 추가합니다.
  2. 응답에 대한 폴링 간격 헤더를 Gitlab::PollingInterval.set_header로 설정합니다.
  3. Gitlab::EtagCaching::Store를 사용하여 엔드포인트의 캐시 무효화를 구현합니다. 리소스가 변경되면 해당 리소스에 종속된 경로의 ETag를 무효화해야 합니다.
  4. 메커니즘이 작동하는지 확인합니다:
    • 요청은 상태 코드 304를 반환해야 합니다.
    • log/development.log에 기록된 SQL 쿼리가 없어야 합니다.

작동 원리

캐시 실패:

캐시 실패

캐시 성공:

캐시 성공

  1. 리소스가 변경될 때마다 임의의 값을 생성하여 Redis에 저장합니다.
  2. 클라이언트가 요청을 보내면 우리는 ETag 응답 헤더를 Redis의 값으로 설정합니다.
  3. 클라이언트는 응답을 캐시(클라이언트 측 캐싱)하고 동일한 리소스에 대한 모든 후속 요청에 If-None-Match 헤더로 ETag를 보냅니다.
  4. If-None-Match 헤더가 Redis의 현재 값과 일치한다면 리소스가 변경되지 않았다는 것을 알기 때문에 데이터베이스를 전혀 쿼리하지 않고 304 응답을 즉시 보낼 수 있습니다. 클라이언트의 브라우저는 캐시된 응답을 사용합니다.
  5. If-None-Match 헤더가 Redis의 현재 값과 일치하지 않으면 리소스가 변경되었으므로 새로운 응답을 생성해야 합니다.

ETag 캐싱을 활성화하려는 엔드포인트에 대해 쿼리 매개변수(예: ?scope=all)를 사용하지 마세요. 미들웨어는 요청 경로만 고려하고 쿼리 매개변수는 무시합니다. 모든 매개변수는 요청 경로에 포함되어야 합니다. 이렇게 함으로써 쿼리 매개변수 순서 문제를 피하고 라우트 일치를 더 쉽게 만듭니다.

자세한 정보: