1. 웹 성능
웹 서버(혹은 WAS, 이하 통칭) 웹 브라우저 요청에 따라 그에 맞는 웹 페이지를 반환
- 웹의 본질은 요청을 주고 결과를 받는것 그 사이의 모든것
- 웹의 성능은 요청을 주었을때 결과를 가능한 빠르게 받는것
- 결과 = HTTP Resources
- HTTP Resources : 웹 페이지 뿐만 아니라 영상, 사진 음성 등
결과 반환 부담을 줄이자
웹 브라우저는 매번 웹 서버에게 요청해서 결과를 받아와야 한다
- 결과가 똑같은 거라면, 웹 브라우저는 매번 웹 서버에게 받아올 필요가 없다
웹 서버는 매번 웹 브라우저의 요청에 대해 결과를 만들어 반환해야한다
- 결과가 똑같은 거라면, 웹 서버는 매번 웹 브라우저에게 만들어 줄 필요가 없다
결과 반환 비용(시간, 네트워크)을 줄이자 : 웹 브라우저
웹 브라우저는 매번 똑같은 100MB짜리 고양이 영상을 웹 서버로부터 받아온다
- 네트워크 트래픽 및 비용 발생
- 100MB 다운로드 완료까지 긴 대기시간 후에야 시청 가능
이전에 받았던 100MB짜리 고양이 영상을 재활용한다면?
- 네트워크 트래픽 및 비용 감소
- 100MB 다운로드 완료의 긴 대기시간 없이 바로 시청 가능 - 유저 경험 증진
결과 생성 비용(노동, 자원)을 줄이자 : 웹 서버
웹 서버는 매번 똑같은 100MB짜리 고양이 팜플렛을 웹 브라우저에게 만들어준다
- 반복 연산 : 컴퓨터 자원(CPU, Memory)소비
- 트래픽 과중 : 모든 유저의 요청에 대한 반복 연산
이전에 만들었던 100MB짜리 고양이 팜플렛을 재활용한다면?
- 반복 연산 감소 : 컴퓨터 자원(CPU,Memory)여유
- 트래픽 분산 : 반복되는 모든 유저의 요청 처리 가능
2. HTTP Cache : 중간 임시 저장소
- 웹 브라우저와 웹 서버는 반복되는 요청에 대해 부담을 나누기 위한 기술을 도입 : HTTP Cache
- 웹 브라우저와 웹 서버 사이 HTTP Cache를 놓고, 그곳에 재사용하려는 HTTP Resources 결과 저장
캐시 용어의 범용성
캐시(명사) : 임시(단기적 : 기간 설정 or 알고리즘 설정)로 재사용할 내용을 저장
- CPU 캐시 : CPU 연산을 위해 메모리에서 값 가져와 사용 후 폐기(칩셋)
- HTTP 캐시 : 웹 요청에 따른 결과를 임시 저장 후 반복 요청 시 저장본 반환
- 서버 캐시 : LRU-Cache '로컬 캐시' 혹은 인메모리 DB Redis'글로벌 캐시'
- LRU : Least Recently Used = 가장 오랫동안 사용되지 않는것 먼저 폐기
캐시(동사) : "임시 저장해"의 의미
HTTP Cache 종류
임시 저장 데이터를 누가 필요로 하는가? 특정된 한명인가, 불특정 다수인가?
- 클라이언트에 붙어있다면, 해당 웹 브라우저만을(유저 한명만을) 위한것 : Private Cache
- 서버에 가까이 있다면, 모든 웹 브라우저들을(다수 유저를) 위한것 : Shared Cache(Public Cache)
Private : 해당 웹 브라우저만을 위해
- 웹 브라우저에 위치
- 브라우저 캐시 : 웹 서버 HTTP Cache 헤더(Cache-control)통한 제어
Shared : 모든 웹 브라우저들을 위해
- 웹 브라우저, 웹 서버 사이에 위치
- 프록시 캐시 : 웹 서버 HTTP Cache헤더(Cache-control)통한 제어
- 관리형 캐시 : 서비스 개발자가 직접 정책 제어, 배포
HTTP Cache 동작
- 캐시 활용 여부 = 실시간성이 중요한 데이터는 성능에 문제가 되더라도 캐시는 사용하지 않는것이 맞다.
- 재검증 = 데이터 원 주인인 웹 서버에 캐시되어 있는 데이터의 유효성(신선도) 체크
- 재검증 주기 = 캐시되어 있는 데이터를 얼마의 주기로 재검증할지
- 데이터가 얼마의 주기로 갱신되는지, 데이터 특성에 따라 개발자가 설정하면 된다
- 재검증 기준 = 캐시되어있는 데이터의 유효성(신선도)여부 판단 근거
HTTP Cache 제어 : Cache-control 헤더를 통한 세부 설정 방법
-
서버의 제어 : HTTP Cache 사용 여부 및 기간, 저장 장소 등 정책 전달을 위해 헤더 사용
- 캐시 저장 여부 : 해? 말아?
- no-store : 캐시 안함
- no-cache : 캐시 함. 단, 매번 재검증 후 사용(패킷 경량화)
- 캐시 저장 장소 : 어디에 저장해?
- public : Private+Shared 모두에 저장
- private : Private에만 저장
- 캐시 재검증 주기 : 얼마가 지나면 재검증해?
- max-age : Expires(유효시간)으로 변환되기 때문에, 기존 Expires가 있어도 엎어쓴다
- 매번 재검증 예)max-age=0 = no-cache
- s-maxage : 프록시 캐시에만 적용되는 유효기간
- 캐시 적용 예)s-maxage=31536000,max-age=0
- 재검증 강제
- must-revalidate : max-age에 도달하였을 때 꼭 재검증이 완료된 뒤 사용하도록 강제
- max-age에 도달하였을 때, 서버와의 접속 문제로 재검증 실패 시 기존엔 그냥 기존것 반환
- must-revalidate가 활성화되어 있다면 504에러 발생
-
재검증 : 캐시 소유자가 서버에게 자신이 가진 캐시 데이터 전달 및 유효성(신선도) 검증 받는 행위
- 조건부 요청 : 재검증 기준이 되는 값을 서버에게 보낸다
- Last-Modified 대응 : 캐시가 유효한지 여부를 시간을 기반으로 판단한다(전송 Resource의 마지막 수정일)
- 캐시 소유자 : If-Modified-Since(바뀌었어?)
- 서버 답변 : 바뀌었어 : 200+Resource Cache
- 서버 답변 : 안바뀌었어 : 304Not Changed
- 캐시 소유자 : If-Unmodified-Since(안바뀌었어?)
- 서버 답변 : 안바뀌었어 : 304 Not Changed
- Etag 대응 : 캐시가 유효한지 여부를 고유값(해시,ID)을 기반으로 판단한다(전송 Resource의 고유값)
- 캐시 소유자 : If-None-Match(바뀌었어?)
- 서버 답변 : 바뀌었어 : 200+Resource Cache
- 캐시 소유자 : If-Match(안바뀌었어?)
- 서버 답변 : 안바뀌었어 : 304 Not Changed
-
HTTP Cache 제어 중 SWR(stale-while-revalidate)확장 디렉티브 전략
-
현재에 캐싱된 컨텐츠를 즉시 로드하는 즉시성(Stale 이더라도)
-
미래에 업데이트된 캐싱 컨텐츠가 사용될 수 있도록 보장하는 최신성
-
ex) 60초 이내에 요청이 오는 경우(stale-while-revalidate=60)
- 재검증 요청을 동시에 하면서 오래된 캐시(Stale)를 반환한다.
Cache-Control: max-age=1, stale-while-reevalidate=60

-
0-1초(신선) -> 캐싱된 응답을 "재검증"없이 바로 반환
-
1-60초(오래되었지만 반환 후, 재검증) -> 캐싱된 응답을 바로 반환 + "재검증"요청(백그라운드로)
-
60+초(재검증) -> 캐싱된 응답을 사용하지 않음 + 서버에 요청 보내어 응답 캐싱 및 반환
3. 스크립트 로드 전략 : HTML파싱(DOM생성 중) JS파일 로드 시점 조율
웹 브라우저 내 HTML(DOM) 웹 페이지 로드 속도 향상 : 스크립트 로드 시점 조율
- 웹 브라우저는 페이지 표기를 위해 HTML파일을 위에서 아래로 순서대로 읽으며 DOM Tree 생성
- 중간에 JS가 포함된 'script'를 만난다면 이 또한 DOM요소이기에 완벽하게 로드 및 실행
- 하지만, 이렇게 HTML(DOM) 웹 페이지 로드 중 중간에 'script'의 JS파일을 다 실행한다면
- 문제1 : 다운받은 JS파일을 모두 로드 및 실행하는데 오랜 시간을 기다려야함(DOM로드 지연)
- 문제 2 : 다운받은 JS파일 실행 시 'script'아래 위치한(아직 로드 안된) DOM 접근 불가
- 문제 3 : 'script'를 맨 아래에 내린다 하더라도 HTML이 크다면 스크립트 실행 시기는 늦음

- Defer : (실행)지연 스크립트
- 병렬 : HTML 파싱 -> 스크립트 호출(로딩) -> HTML 파싱 끝난 후 실행
- Async : (실행)비동기 스크립트
- 병렬 : HTML 파싱 -> 스크립트 호출(로딩)+바로 실행 -> HTML 파싱
- 스크립트 호출이 끝난다면 HTML 파싱을 잠시 멈추고, 스크립트 실행
- 동기(Synchronous, 실시간성) : 요청-작업이 완료될 때 까지 하던 작업 멈추고 대기
- 비동기(Asynchronous, 비실시간성) : 요청-작업이 완료되든말든 하던 작업 그대로 진행
- 작업이 완료되면, 완료되었다는 응답을 받음:Callback
4. 결과 반환 시간 단축
HTTP Cache 상세 : Proxy와 CDN
proxy는 캐싱 + 요청에 대한 세부적 추가 작업을 위해 사용한다
- 캐싱 : 요청에 따른 응답을 중간 저장해놓은 뒤 동일 요청 시 저장값 반환
- 요청에 대한 세부적 추가 작업 : 요청 변환, 필터 등의 추가 작업 수행
CDN은 캐싱 + 지역성 해결을 위해 사용한다
- 캐싱 : 요청에 따른 응답을 중간 저장해놓은 뒤 동일 요청 시 저장값 반환
- 지역성 해결 : HTTP Resource 제공 서버와 클라이언트가 멀리 떨어진 경우 클라이언트에 가까운 곳에 저장
Forward Proxy : 클라이언트 성능 및 보안
- 요청 보내는 측 : 클라이언트(웹 브라우저)
- 요청에 대한 세부적 추가 작업
- 클라이언트 은닉 : IP 변환을 통해 원 요청자 은닉
- 클라이언트 접근 제어 : 특정 IP 혹은 웹 페이지에 대한 접근 금지
- 캐싱 : 클라이언트가 받을 요청을 중간에 임시 저장(개인이 소비하는 입장에서)
Reverse Proxy : 웹 서버 성능 향상, 부하 완화 및 보안
- 요청을 받는 측 : 웹 서버
- 요청에 대한 세부적 추가 작업
- 요청 변환 : Header 세팅
- 요청 전달 : URL Mapping(Routing), 로드 밸런싱(요청 분산)
- 로드 밸런싱(요청 분산) = 웹 서버 부하 완화
- 웹 서버 수 동적으로 늘리기 -> SRE의 업무(고가용성)
- 서버 은닉 : 서버 고유의 IP가 외부로 노출되지 않음
- 서버 접근 제어(요청 필터) : DDoS 방지 - Traffic 제어, Response Max Size, Timeout 세팅
- Rate Limiting
- WAF(Web Application Firewall)
- Honeypot에 저장된 악성 IP리스트 활용한 블럭
- Custom IP 추가 가능(예, 악성 크롤링 봇 블럭)
- 보안 : HTTPS
- 모든 서버가 Private Key를 가지고 있어야 하는 단점
- 한 서버(Reverse Proxy)가 Private Key를 가지고 있으면 관리 및 인증 간편
- 캐싱 : 클라이언트가 자주하는 요청에 대한 응답을 중간에 임시 저장(다수에 제공하는 관점에서)
CDN(Content Delivery Network) : 웹 서버 성능 향상, 부하 완화
- 미국 웹 서버가 제공하는 HTTP Resource를 한국 클라이언트에서 조회시 물리적인 거리에 의한 긴 응답시간
- 전세계적으로 캐시 서버를 곳곳에 두어 중간에 저장해 놓는다면, 각국에서 필요한 정보들을 빠르게 취할 수 있음
- 캐시 서버로 동작하는 만큼 원 서버에 문제가 생기면 CDN이 고가용성을 보장해주는 버퍼의 역할을 해주기도 함