2023. 11. 10. 13:17ㆍ네트워크
먼저 캐시는 왜 필요할까?
1.1MB 용량의 똑같은 사진을 요청할 때마다 보낸다고 생각해보자.
네트워크는 속도가 느리고 비싸다.
이에 따라 브라우저 렌더링하는 속도가 느려진다.
그러면 사용자 경험도 떨어진다.
굳이 똑같은 사진을 또 요청할 필요가 있을까?
캐시를 저장해두면 된다.
웹브라우저 캐시에 저장을 해두면 웹브라우저는 이를 보고 있으면 여기서 불러온다.
그러면 속도가 빨라져 렌더링 속도도 빨라지고 사용자 경험도 좋아진다.
서버에서 캐시에 저장하라고 할때 cache-control: max-age=초 헤더를 사용한다.
몇초동안 캐시로 저장하라는 것이다.
이 시간 동안은 웹브라우저가 캐시를 이용한다.
캐시 유효시간이 지나면 못쓴다.
다시 요청을 해야한다.
근데 만약 서버에서 보내려는 데이터가 캐시에 있는 데이터와 완전히 같다면 데이터 자체를 보낼 필요가 있을까?
이를 해결하기 위해 서버는 처음 응답을 보낼때 Last-Modified라는 헤더를 함께 보낸다.
이 헤더는 최근 수정일을 나타낸다.
그러면 웹브라우저는 캐시를 저장할때 이 헤더도 같이 저장한다.
그리고 캐시 유효시간이 초과되면 if-modified-since라는 요청 헤더를 붙인 다음 보낸다.
그러면 서버가 만약 이 시간 이후로 last-modified가 바뀌었다면 데이터를 담아 보낸다.
만약 바뀌지 않았다면 start-line에 304 Not Modified를 보낸다.
이때 body는 없다.
그러면 웹브라우저는 지금 받은 헤더 정보로 캐시의 헤더정보를 다시 갱신한다.
그리고 이 캐시 데이터를 다시 사용한다.
이렇게 하면 네트워크 용량은 필요해지지만 바디 정보는 안받고 헤더만 받기에 효율이 올라간다.
굉장히 실용적인 해결방안이다.
웹브라우저에서 새로고침을 누르면 웹브라우저는 캐시가 아닌 서버에 다시 요청을 한다.
이때 if-modified-since를 보낸다.
또 하나의 캐시 검증 헤더로 ETag가 사용된다.
조건부 요청 헤더로는 If-None-Match가 사용된다.
조건이 만족하면 200 OK, 아니면 304 Not Modified를 보낸다.
ETag는 Last-Modified 태그와는 달리 서버에서 캐시 검증 로직을 관리한다.
ETag가 같으면 body를 보내지 않는다. 다르면 보낸다.
ETag는 hash값으로도 구현할 수 있고 구현하기 나름이다.
Last-Modified의 단점은 초 단위 변경은 캐시 조정이 불가능하다는 것이다.
ETag(Entity Tag)는 수정했지만 결국 같은 데이터인 경우나 크게 변경이 없는 사항에서는 캐시 정보를 사용하도록 하고 싶을 경우 사용된다.
애플리케이션 배포 주기에 맞추어 ETag를 모두 갱신하도록 할 수 있다.
그외는 둘이 똑같다.
캐시의 컨트롤 헤더에는 다음의 것들이 있다.
1. Cache-Control
2. Pragma
3. Expires
1. Cache-Control
현재 제일 많이 사용된다. 다음 세가지가 있다.
1. max-age: 남은 시간을 초 단위로 부여한다. 유연성이 좋다.
2. no-cache: 데이터는 캐시로 저장할 수 있되 항상 origin 서버에 검증을 해야한다.
3. no-store: 데이터에 민감한 정보가 있으므로 저장하지 않고 메모리에서만 사용해야 한다.
2. Pragma
no-cache: Cache-Control의 것과 동일한 기능이지만 HTTP 1.0 하위 호환이기 때문에 잘 사용하지 않는다.
3. Expires
구체적인 시간을 지정한다. 유연성이 떨어진다.
HTTP 1.0부터 사용했다.
Cache-Control의 max-age와 함께 사용되면 무시된다.
조건부 요청 헤더에는 4가지가 있다.
If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since
프록시 캐시 서버는 클라이언트와 원서버 사이를 중계하는 서버이다.
원서버에서 받으려면 거리가 멀면 시간이 오래 걸린다.
프록시 서버는 한국 어딘가에 둔다.
직접 접근하는 것이 아니라 거쳐서 접근하도록 한다.
프록시 캐시 서버에 저장하는 캐시를 public cache, 클라이언트에 저장하는 캐시를 private cache라고 한다.
이와 관련된 Cache-Control에는 다음의 것들이 있다.
1. Cache-Control: public: 프록시 서버에도 저장할 수 있다.
2. Cache-Control: private: 프록시 서버에도 저장할 수 없다. 기본은 private이다.
3. Cache-Control: s-maxage: 프록시 서버에 언제까지 있을 수 있다.
4. Age: 오리진 서버에서 응답 후 프록시 서버에서 머문 시간. 클라이언트에 전달된다.
웹브라우저는 임의로 캐시를 저장하는 경우가 있다.
이를 완벽하게 무효화하기 위해서는 다음을 한번에 사용한다.
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Pragma는 하위 호환 때문에 넣는다.
must-revalidate는 캐시 만료후 최초 조회 시 원 서버에 검증해야 한다.
원 서버 접근 실패시 반드시 오류가 발생해야한다. (504 Gateway Timeout)
no-cache는 프록시 캐시 서버와 원서버가 단절이 되면 프록시 캐시 서버가 응답을 한다. 근데 이게 되게 옛날일 수도 있다.
하지만 must-revalidate를 사용하면 이런 경우 에러가 나도록 막아서 무조건 원서버로부터 응답을 받도록 한다.
Reference
'네트워크' 카테고리의 다른 글
[네트워크] LAN과 WAN에 대한 나름의 이해 (0) | 2023.12.18 |
---|---|
[네트워크] IPv4와 IPv6에 대한 나름의 이해 (1) | 2023.12.17 |
[네트워크] 인증 헤더와 쿠키 헤더에 대한 나름의 이해 (1) | 2023.11.09 |
[네트워크] 특별한 정보를 담고 있는 헤더에 대한 나름의 이해 (0) | 2023.11.09 |
[네트워크] 일반 정보 헤더에 대한 나름의 이해 (0) | 2023.11.09 |