본문 바로가기
Spring/스프링을 위한 HTTP 기본 지식

#8 HTTP 헤더_캐시와 조건부 요청

by 히포파타마스 2021. 6. 18.

HTTP 헤더_캐시와 조건부 요청

 

1. 캐시

이미지와 같이 크기가 큰 데이터를 전송 받아야 할 경우 매 요청 마다 데이터를 다운로드 받아야 한다.

 

매번 데이터를 다운받아야 하기 때문에 위와 같은 방식은 속도적인 부분에서 손해가 크다.

 

캐시는 서버에서 전송받은 데이터를 클라이언트가 저장하고 같은 요청 시 해당 데이터가 유효할 경우(수정되지 않았거나 바뀔필요가 없는 경우) 저장된 데이터를 사용하는 방식을 사용한다.

 

여기서 캐시는 저장된 데이터를 의미한다. 

 

 

[캐시 적용 1]

클라이언트의 요청에 서버는 cache-controrl 헤더로 응답 데이터가 캐시로 저장될 수 있으며, 만료기간이 60초라는 정보를 제공한다. 

 

 

[캐시 적용2]

클라이언트는 응답 헤더에 제공된 정보를 토대로 응답 결과를 저장한다.

 

 

[캐시 적용3]

이 후의 같은 요청에 대해서 클라이언트는 캐시가 유효한지(기간, 수정) 검증한 뒤 저장된 캐시를 사용해 데이터를 조회한다.

 

 

이처럼 캐시를 사용하므로써 매번 네트워크를 사용하지 않아도 되기 때문에 네트워크 사용량을 줄일 수 있고 브라우저 로딩 속도를 향상 시킬 수 있다.

 

단 캐시 시간(유효 기간)이 초과하면 서버를 통해 데이터를 다시 조회하고 캐시를 갱신해야 한다.

 

이 때는 다시 네트워크 다운로드가 발생한다.

 

 

2. 검증 헤더와 조건부 요청 - Last-modified

캐시 기간이 만료되었어도 서버가 제공하는 데이터가 수정되지 않았다면, 저장된 캐시는 유효하기 때문에 계속해서 캐시를 사용해도 될것이다.

 

즉 서버가 제공하는 데이터가 수정되지 않는것만 확인할 수 있으면 캐시 기간이 만료되어도 계속해서 저장된 캐시를 사용할 수 있다.

 

HTTP는 검증 헤더를 추가하는것으로 캐시가 수정되었는지를 판단하는 정보를 제공한다.

 

 

[검증 헤더_Last-Modified 1]

서버는 캐시로 저장될 데이터에 최종 수정일을 Last-Modified 헤더에 명시한다.

 

 

[검증 헤더_Last-Modified 2]

브라우저는 캐시 기간, 데이터 최종 수정에 대한 정보와 함께 응답 결과를 캐시에 저장한다.

 

 

[검증 헤더_Last-Modified 3]

같은 요청을 했을 때 캐시 유효기간이 지났을 경우, 클라이언트는 캐시에 저장된 "데이터 최종 수정일"에 대한 정보를 토대로 if-modified-since 헤더를 이용해 서버의 데이터가 변경되었는지 여부를 확인한다.

 

 

[검증 헤더_Last-Modified 4]

데이터 최종 수정일이 변경되지 않았으면 서버는 304 상태코드로 응답하고 로컬 캐시로 리다이렉트(이 때문에 HTTP Body가 없다)한다.

 

 

[검증 헤더_Last-Modified 5]

클라이언트는 캐시 유효기간을 갱신하고 응답 결과를 재사용한다.

 

결과적으로 네트워크 다운로드가 발생하지만 용량이 매우 적은 헤더 정보만 다운하면 된다.

 

※ If-Modified-Since 헤더 이후에 데이터가 수정되었으면 서버는 200 OK 상태코드를 반환한다.

 

 

3. 검증 헤더와 조건부 요청 - ETag

Last-Modified을 사용하는 검증 방식은 는 몇가지 단점이 있다.

 

· 1초 미만 단위로 캐시 조정이 불가능

· 날짝 기반

· 데이터를 수정해서 수정날짜가 변경되었지만 데이터 결과가 같을 경우

· 서버에서 별도로 캐시 로직을 관리하고 싶은 경우

 

위와 같은 단점을 어느정도 커버하는 ETag 헤더를 이용한 검증 방식이 있다.

 

ETag는 캐시에 고유한 버전 태그를 달아두고 데이터가 변경되면 이 태그를 바꾸어 데이터가 변경됨을 알린다.

 

이제 클라이언트는 ETag가 같은지 아닌지만을 판단해서 캐시를 유지할 지, 데이터를 다시 다운할지를 결정하면 된다.

 

캐시 관리 로직은 온전히 서버가 관리하게 된다.

 

 

[검증 헤더 - ETag 1]

서버는 클라이언트의 요청에 데이터와 ETag 헤더를 함께 전송한다.

 

 

[검증 헤더 - ETag 2]

클라이언트는 ETag와 함께 캐시를 저장한다.

 

 

[검증 헤더 - ETag 3]

같은 요청을 다시 할 때, 캐시 유효기간이 만료되었을 경우 저장된 ETag를 토대로 If-None-Match 헤더를 이용해서 데이터가 변경되었는지 여부를 확인한다.

 

 

[검증 헤더 - ETag 4]

데이터가 변경되지 않았으면 Last-Modified 검증방식과 같이 304 상태코드를 반환하고 로컬 캐시로 리다이렉트 한다.

 

 

4. 캐시 제어 헤더

Cache-Control을 이용해 캐시를 다양하게 제어할 수 있다.

 

■ Cache-Control: max-age

 

· 캐시 유효 시간, 초 단위

 

■ Cache-Control: no-cache

 

· 데이터는 캐시해도 되지만, 항상 원(origin) 서버에 검증하고 사용해야된다.

 

■ Cache-Control: no-store

 

· 데이터에 민감한 정보가 있으므로 저장하면 안된다.

 

· 메모리에서 사용하고 최대한 빨리 삭제

 

■ Cache-Control: must-revalidate

 

· 캐시 만료후 최초 조회시 원 서버에 검증해야된다.

 

· 원 서버 접근 실패시 반드시 오류가 발생해야된다(504 Gateway Timeout)

 

· must-revalidate는 캐시 유효 시간이라면 캐시를 사용한다.

 

■ Cache-Control: public

 

· 응답이 public 캐시에 저장되어도 됨

 

■ Cache-Control: private

 

· 응답이 해당 사용자만을 위한 것임

 

· private 캐시에 저장해야 함(기본값)

 

■ Cache-Control: s-maxage

 

· 프록시 캐시에만 적용되는 max-age

 

 

5. 프록시 캐시

클라이언트와 서버가 물리적으로 거리가 멀 경우 통신에 시간이 더 오래 걸릴 수 있다.

 

이를 해결하기 위해 보다 물리적으로 가까운 서버에 원 서버의 데이터를 캐시로 받아 이용 할 수 있다.

 

이 때 원 서버의 데이터가 캐시로 저장되는 서버를 프록시 캐시 서버라한다.

 

프록시 캐시 서버에 저장된 캐시는 프록시 캐시, public 캐시라고 한다.

 

 

[프록시 캐시] 

개개인인 클라이언트가 저장하는 캐시는 private 캐시라고 한다.

 

■ Age(헤더)

 

· 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간

 

■  캐시 무효화

 

프록시 캐시 서버를 경유 할 경우 일반적으로는 프록시 캐시 서버에서 데이터의 유효성을 검증한다.

 

그러나 일부 중요한 데이터 정보는 반드시 원 서버의 검증을 거쳐야 한다.

ex) 매우 중요한 돈과 관련된 결과, 순간적으로 원 서버와 프록시 서버의 연결이 끊길 경우 큰 문제 발생

 

반드시 원 서버의 검증을 거쳐야하는 중요한 데이터에 대해서는 다음과 같은 캐시 제어 헤더를 사용한다.

 

Cache-Control: no-cache, no-store, must-revalidate

 

no-cache나 must-revalidate를 단독으로 사용하면 원 서버 접근시 오류가 발생하지 않거나 원 서버에 검증 하지 않는 경우도 생기기 때문에 반드시 같이 사용해야 된다.

 

또한 중요도가 높은 데이터는 되도록 저장되지 않는 것이 바람직 하기 때문에 no-store를 사용한다.

 

 

[캐시 무효화 - no-cache 1]

no-cache를 사용하면 항상 원 서버에 검증한다.

 

 

[캐시 무효화 - no-cache 2]

하지만 원 서버 접근이 불가능 할 경우 서버 설정에 따라 캐시 데이터를 반환 할 수 도있다.

 

 

[캐시 무효화 - must-revalidate]

must-revalidate는 원 서버 접근 불가시 항상 오류가 발생한다.

 

이 때문에 원 서버 접근시 변경 가능성이 있는 데이터(프록시 캐시)를 반환하지 않기 때문에 신뢰성을 보장한다.

'Spring > 스프링을 위한 HTTP 기본 지식' 카테고리의 다른 글

#7 HTTP 헤더_일반 헤더  (0) 2021.06.17
#6 HTTP 상태코드  (0) 2021.06.17
#5 HTTP_메서드 활용  (0) 2021.06.17
#4 HTTP_메서드  (0) 2021.06.16
#3 HTTP_기본 속성  (0) 2021.06.16

댓글