Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 자바의 정석 기초편 ch11
- 스프링 mvc1 - 서블릿
- 스프링 고급 - 스프링 aop
- 스프링 mvc1 - 스프링 mvc
- 스프링 db1 - 스프링과 문제 해결
- 스프링 mvc2 - 로그인 처리
- 스프링 mvc2 - 타임리프
- 스프링 db2 - 데이터 접근 기술
- 자바의 정석 기초편 ch4
- 자바의 정석 기초편 ch13
- 자바의 정석 기초편 ch14
- jpa - 객체지향 쿼리 언어
- 코드로 시작하는 자바 첫걸음
- 2024 정보처리기사 시나공 필기
- 자바의 정석 기초편 ch9
- 스프링 입문(무료)
- 자바의 정석 기초편 ch12
- 스프링 mvc2 - 검증
- 자바의 정석 기초편 ch5
- 자바의 정석 기초편 ch7
- 자바의 정석 기초편 ch6
- 자바의 정석 기초편 ch1
- 2024 정보처리기사 수제비 실기
- 자바의 정석 기초편 ch8
- 자바의 정석 기초편 ch3
- jpa 활용2 - api 개발 고급
- @Aspect
- 자바의 정석 기초편 ch2
- 타임리프 - 기본기능
- 게시글 목록 api
Archives
- Today
- Total
나구리의 개발공부기록
HTTP 헤더2 - 캐시와 조건부 요청, 캐시 기본 동작, 검증 헤더와 조건부 요청, 캐시와 조건부 요청 헤더, 프록시 캐시, 캐시 무효화 본문
인프런 - 스프링 완전정복 코스 로드맵/모든 개발자를 위한 HTTP 웹 기본 지식
HTTP 헤더2 - 캐시와 조건부 요청, 캐시 기본 동작, 검증 헤더와 조건부 요청, 캐시와 조건부 요청 헤더, 프록시 캐시, 캐시 무효화
소소한나구리 2024. 2. 6. 12:46출처 : 인프런 - 모든 개발자를 위한 HTTP 웹 기본 지식(유료) / 김영한님
유료 강의이므로 정리에 초점을 두고 코드는 일부만 인용
1. 캐시 기본 동작
1) 기본 동작 설명
(1) 캐시가 없을 때
- 데이터가 변경되지 않아도(같은 요청을 여러번) 계속 네트워크를 통해서 데이터를 다운로드 받아야함
- 인터넷 네트워크는 PC의 메모리나 하드디스크에 비에 상대적으로 매우 느리고 비쌈
- 사용자 입장에서는 브라우저 로딩속도가 느려짐(느린 사용자 경험)
(2) 캐시 적용
- cache-control(캐시 유효시간) 이라는 메시지를 HTTP헤더에 넣을 수 있음
- 최초요청시 서버에서 받은 응답 결과를 캐시에 저장하고 같은 요청이 오게 되면 브라우저 캐시에서 조회하여 결과를 응답
- 캐시 덕분에 캐시 유효시간동안 네트워크를 사용하지 않아도 됨
- 비싼 네트워크 사용량을 줄일 수 있고 브라우저 로딩 속도가 매우 빠름(빠른 사용자 경험)
- 예) 웹 브라우저 들어갔던곳을 다시 재접속 했을 때 굉장히 빨리 열림
(3) 유효 시간이 초과
- 캐시 유효시간이 초과하면 브라우저 캐시에 동일한 데이터가 있음에도 서버를 통해 데이터를 다시 조회하고 캐시를 갱신하고 다시 네트워크 다운로드가 발생 됨
2. 검증 헤더와 조건부 요청
1) 캐시 시간 초과
(1) 캐시 유효 시간이 초과해서 서버에 다시 요청하면 두가지 상황이 나타남
- 서버에서 기존 데이터를 변경함
- 서버에서 기존 데이터를 변경하지 않음
(2) 서버에서 기본 데이터를 변경하지 않았을 경우
- 캐시 만료 후에도 서버에서 데이터를 변경하지 않았을 경우 데이터를 전송하는 대신 저장해 두었던 캐시를 재사용 할 수 있음
- 단, 클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법이 필요함 - 검증 헤더 추가로 해결
2) 검증 헤더 추가
(1) 첫 번째 요청
- Last-Modified(마지막으로 수정된 시간)를 추가해서 서버에 요청 (시간은 UTC 표기법으로 작성)
- 서버에서는 응답 데이터에 요청한 데이터의 최종 수정일 정보를 함께 포함하여 웹 브라우저에 전송하고 웹 브라우저는 응답 결과를 캐시에 저장
(2) 두 번째 요청 - 유효기간 초과
- 캐시 유효 시간이 지난 후 클라이언트에서 동일한 요청이 한번 더 올 경우 브라우저에 저장된 데이터의 최종 수정일 정보를 서버에 전송
- 서버에서는 웹브라우저가 요청한 데이터를 최종 수정일로 비교하여 데이터가 동일한지(수정이 안되었는지) 검증을 하고 데이터가 같으면 304 Not Modified 상태코드와 함께 HTTP Body가 없는 응답 메시지를 웹 브라우저에 전송
- 실제 데이터(HTTP body)는 없이 헤더의 정보만 웹 브라우저에 전송되므로 용량이 크게 줄어들어 네트워크 부하가 감소됨
- 브라우저캐시가 응답메시지를 받아 동일한 데이터임을 확인하여 캐시를 다시 세팅(캐시유효기간)
- 브라우저에서 요청한 데이터를 캐시가 조회하여 전송
(3) 정리
- 캐시 유효 기간이 초과해도 서버의 데이터가 갱신되지 않으면 304 Not Modified 상태코드와 헤더 메타 정보만 응답함
- 클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보를 갱신하고 캐시에 저장되어있는 데이터를 재활용
- 결과적으로 네트워크 다운로드가 발생하지만 용량이 매우 적은 헤더 정보만 다운로드하기때문에 매우 실용적으로 문제가 해결 됨
3) 검증헤더와 조건부 요청 헤더
(1) 검증헤더
- 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
- Last-Modified, ETag
(2) 조건부 요청 헤더
- 검증 헤더로 조건에 따른 분기를 서버에 요청
- If-Modified-Since: Last-Modified 사용
- If-None-Match: ETag 사용
- 조건이 만족하면 200 OK
- 조건이 만족하지 않으면 304 Not Modified
4) If-Modified-Since 이후 데이터 변경/미변경 예시
(1) 데이터 미변경
- 캐시에 저장된 데이터와 서버의 저장된 데이터가 마지막 수정날짜까지 동일
- 304 Not Modified 상태코드와 헤더 데이터만 전송(Body 미포함)
- 전송 용량이 크게 줄어듦
(2) 데이터 변경
- 캐시 : ... 10일 10:00:00 vs .... 10일 11:00:00 / 차이발생
- 200 OK 모든 데이터 전송(Body 포함)
- 최초에 요청된 데이터의 용량이 전송 됨
(3) Last-Modified, If-Modified-Since 단점
- 1초 미만(0.x초) 단위로 캐시 조정이 불가능
- 날짜 기반의 로직 사용하기 때문에 데이터를 수정해서 날짜가 달라졌지만 최종 데이터의 수정 결과가 원본의 데이터와 같은 경우에도 전체 데이터를 다시 전송함 (복사-붙여넣기, 수정 후 원복 등)
- 서버에서 별도의 캐시 로직을 관리하고 싶은 경우 방법이 없음
5) ETag, If-None-Match
(1) ETag: Entity Tag
- 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠(버전으로 표시, 임의값 지정, Hash라이브러리를 통해서 Hash값을 지정 등)
- 데이터가 변경되면 임의의 고유한 값(ETag) 이름을 바꾸어서 저장
- Hash값을 ETag로 지정하는 경우 파일이 완전히 동일하면 같은 Hash값을 주기 때문에 이런경우 캐시가 그대로 적용 될 수 있음
- 클라이언트 입장에서 ETag만 보내서 같으면 유지, 다르면 다시 데이터를 받아서 저장
(2) 첫 번째 요청
- 최초 데이터 요청시 서버에서 데이터에 ETag를 생성해서 응답
- 캐시는 응답 결과를 캐시에 저장
(3) 두 번째 요청
- 캐시 유효 기간이 지난 후에 웹 브라우저에서 다시 동일한 요청을 하면 캐시에 저장된 ETag 값을 꺼내서 'If-None-Match: ETag값' 으로 서버에 전송(ETag값과 매치된 값이 없으면 새로운 데이터를 보내라!)
- 서버에서는 받은 ETag값과 동일한 ETag값을 가진 데이터를 찾아 데이터가 수정되었는지 검증
- 서버에서 찾은 ETag값과 요청온 ETag값이 일치하면 요청이 실패하여 304 Not Modified 상태 코드를 헤더에 반영하고 클라이언트에 전송(HTTP Body는 미포함)
- 브라우저 캐시는 응답 받은 헤더 데이터만 갱신하고(유효시간 재설정) 기존 데이터는 유지
- 웹브라우저에서 요청한 데이터를 캐시에서 조회하여 응답
(4) 정리
- 단순히 ETag만 서버에 보내서 같으면 유지하고 다르면 다시 받는 메커니즘
- 캐시 제어 로직을 서버에서 완전히 관리하고 클라이언트는 단순히 이 값을 서버에 제공(클라이언트는 캐시 메커니즘을 모름)
- 예) 애플리케이션 배포 주기에 맞추어서 ETag를 모두 갱신
3. 캐시와 조건부 요청 헤더
1) 캐시 제어 헤더
- Cache-Control: 캐시 제어
- Pragma: 캐시 제어(하위 호환)
- Expires: 캐시 유효 기간(하위 호환)
(1) Cache-Control: 캐시 지시어 (Directives)
- Cache-Control: max-age : 캐시 유효 시간, 초 단위
- Cache-Control: no-cache: 데이터는 캐시해도 되지만 중간 캐시 서버가 아닌 항상 원 서버(origin서버)에 데이터를 검증하고 사용
- Cache-Control: no-store: 데이터에 민감한 정보가 있으므로 저장하면 안됨(메모리에서 사용하고 최대한 빨리 삭제)
(2) Pragma(캐시 제어)
- Pragma: no-cache
- HTTP 1.0 하위호환으로 지금은 거의 사용하지 않음
(3) Expires(캐시 만료일 지정)
- expires: Mon, 01 Jan 1990 00:00:00 GMT
- 캐시 만료일을 정확한 날짜로 지정
- HTTP 1.0 부터 사용했지만 지금은 더 유연한 Cache-Control: max-age를 사용함(권장)
- Cache-Control: max-age와 함께 사용되면 Expires는 무시됨
2) 검증헤더와 조건부 요청 헤더 정리
(1) 검증 헤더(Validator)
- ETag: "V1.0", ETag: "asldf238" 등등
- Last-Modified : Thu, 02 Jan 2020 00:00:00 GMT
(2) 조건부 요청 헤더
- If-Match, If-None-Match: ETag 값 사용
- If-Modified-Since, If-Unmodified-Since: Last-Modified 값 사용
4. 프록시 캐시
(1) 원 서버(진짜서버, origin 서버) 직접 접근 - 요청시 진짜 데이터가 있는 서버
- 웹브라우저가 요청할 때마다 실제 서버에 접근하게되면 속도가 매우 느려짐
(2) 프록시 캐시 도입(캐시서버)
- 중간에 서버를 도입해서 요청 시 원서버에 접근하는 것이 아니라 캐시서버에 접근하여 데이터를 전송 받음
- 물론 최초 요청(캐시서버에 데이터가 없는 경우)은 원서버에서 데이터를 가져와야하고 그 이후부터는 캐시 서버에 저장된 데이터를 받게 됨
- 웹 브라우저에 있는 캐시(로컬 캐시) : private 캐시
- 프록시 캐시 서버: public 캐시
(3) 캐시 지시어 - 기타
- Cache-Control: public : 응답이 public 캐시에 저장 되어도 됨
- Cache-Control: private : 응답이 사용자만을 위한 값, private 캐시에 저장(기본값)
- Cache-Control: s-maxage : 프록시 캐시에만 적용되는 max-age
- Age: 60(HTTP 헤더) : 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)
5. 캐시 무효화
1) 캐시 지시어 - 확실한 캐시 무효화 응답
- 캐시를 적용하지 않아도 웹 브라우저가 GET요청인 경우에는 임의로 캐시를 해버리게 됨(휴리스틱하게 한다?)
- 해당 페이지를 정말 캐시가 되면 안되라고 지시할 경우 명령어를 다 넣어줘야함
- Cache-Control: no-cache, no-store, must-revalidate
- Pragma:no-cache (HTTP 1.0 이전 브라우저에서 요청이 올 것을 대비)
(1) Cache-Control: no-cache
- 데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용
(2) Cache-Control: no-store
- 데이터에 민감한 정보가 있으므로 저장하면 안됨(메모리에서 사용 후 최대한 빨리 삭제)
(3) Cache-Control: must-revalidate
- 캐시 만료 후 최초 조회시 원 서버에 데이터를 검증해야함
- 원 서버 접근 실패 시 반드시 오류가 발생해야함(504 Gateway Timeout)
- 캐시 유효 시간 내에 요청은 캐시를 사용
(4) Pragma:no-cache : HTTP 1.0 하위 호환
2) no-cache vs must-revalidate
(1) no-cache
- 웹 브라우저에서 no-cache+ETag를 달고 요청을 하면 프록시 캐시가 아닌 원래의 서버에서 응답을 함
- 만약 원서버에 접근이 불가능할 경우(여러 외부의 요인) 오류가 아닌 프록시 데이터가 가진 데이터(오래된 데이터라도)를 응답하도록 프록시 서버가 세팅 되어있음
- 요청했던 데이터가 최신 데이터가 아닐 수 있음(예 - 통장 잔고의 데이터가 과거의 것으로 출력되면 문제가 발생 될 수 있음)
(2) must-revalidate
- 원 서버에 접근이 불가능할 경우 무조건 504 Gateway Timeout 에러를 발송함
- 잘 발생하지는 않지만 확실하게 하려면 해당 캐시 지시어까지 포함해야 완벽한 캐시 무효화를 할 수 있음