해결책
HTTP Vary 헤더는 캐시에 어떤 요청 헤더가 응답에 영향을 줄 수 있는지 알려주므로, 캐시가 브라우저용 HTML을 JSON을 요청하는 API 클라이언트에 제공하는 일이 없다. Cloudflare는 약 5만 개의 인기 사이트에 걸친 1억 2천만 건 이상의 응답을 분석한 외부 연구를 인용하며, 거의 3,000개가 네 개 이상의 필드에 따라 달라지고 일부는 10개, 23개, 심지어 47개 필드에 따라 달라진다고 밝혔다. Vary는 올바르지만 문자 그대로 받아들이면 캐싱을 거의 무용지물로 만들 수 있다. 세 개 필드에 걸친 열 개 값만으로도 최대 1,000개의 변형이 생기고, Accept-Language 같은 헤더는 오리진에 같은 의미이면서도 순서나 형식이 다를 수 있다.
그 결과는 '완벽하게 올바르면서도 거의 영구적으로 차가운' 캐시다. 바이트 단위로 동일한 응답이 거의 재사용되지 않는 여러 항목에 흩어져 서로를 밀어내고, 더 많은 요청을 오리진으로 되돌린다. 기존의 우회 방법들—캐시를 완전히 건너뛰거나, Worker에서 협상 로직을 중복 구현하거나, 이미지용 Vary 같은 좁은 기능—은 각각 캐싱을 포기하거나, 애플리케이션 로직을 중복하거나, 한 가지 사례만 다루었다.
이제 Cache Rules는 오리진이 Vary 헤더를 계속 선언하게 하면서, 규칙 설정이 헤더별로 값을 작은 동등 집합으로 정규화할지, 정확한 값을 그대로 전달할지, 예측할 수 없는 헤더에 대해서는 캐싱을 우회할지 결정한다. 둘 다 영어를 선호하는 두 Accept-Language 요청, en-US, fr;q=0.8과 fr;q=0.8, en-GB는 이제 normalize 아래에서 두 변형이 되는 대신 하나의 캐시 항목을 공유할 수 있고, 정확히 달라져야 하는 헤더는 passthrough를 사용할 수 있다. 이 기능은 현재 Free부터 Enterprise 플랜까지 제공된다.
달성한 것
무엇이 달라지는가와 얼마나 많은 변화가 중요한가를 분리한다
Accept와 Accept-Language를 품질 값 기준으로 정렬하고 구성된 형식 집합으로 잘라내어 정규화하면, 바이트는 다르지만 의미상 동일한 요청들이 하나의 항목으로 합쳐진다.
normalize/passthrough/bypass 선택을 전역이 아니라 헤더별로 두면, 운영자는 Cookie를 무한한 것으로(bypass) 취급하면서 Accept-Language를 작은 닫힌 집합으로(normalize) 취급할 수 있다.
정규화된 헤더 값을 캐시 키에만 쓰지 않고 오리진으로 전달하면, 오리진의 응답 선택이 어떤 캐시 변형으로 저장되는지와 일치하게 유지된다.
Vary: *는 여전히 항상 캐시를 우회한다. 이는 클라이언트 IP처럼 HTTP 메시지 외부의 요인이 응답을 이끌었다는 신호일 수 있으며, 어떤 헤더 수준 규칙으로도 안전하게 정규화할 수 없기 때문이다.
정확성 메커니즘이 조합적 낭비로 폭발할 때, '다른 바이트'와 '다른 의미'를 같은 것으로 취급하고 있는 지점을 찾아내고, 운영자에게 각각을 위한 별도의 조절 장치를 제공하라.
그 후
Cloudflare는 만료된 IETF Availability Hints 초안의 아이디어를 통해 오리진이 지원하는 표현을 직접 기술하게 함으로써, Cache Rule이 어떤 형식과 언어를 정규화해야 하는지 구성하는 수작업을 줄일 수 있을지 평가하고 있다고 밝혔다. 이 글은 현재의 normalize/passthrough/bypass 구분을 최종 설계라기보다 기존 옵션들(완전 우회, 사용자 지정 캐시 키, Worker 기반 협상 로직) 사이의 공백을 메우는 것으로 규정한다.
근거 확인하기
출처
- We just shipped support for the ugliest part of HTTP: Vary The Cloudflare Blog · blog.cloudflare.com ·