ASAC 07기 : 24.12.16 웹 브라우저 성능 개선 및 웹 서버 부하 완화를 위한 HTTP Cache 와 Proxy

2SEONGA·2024년 12월 18일
0

ASAC

목록 보기
4/13
post-thumbnail

Cache 와 Proxy

HTTP Cache 등장 : 웹 서버 부하 완화 및 웹 페이지 로드 성능 개선

HTTP Cache : 웹 브라우저와 웹 서버 사이 중간 저장소

  • 웹 브라우저 : 웹 페이지 로드 응답이 똑같다면, 웹 브라우저는 매번 웹 서버에게 받아올 필요가 없다.
    • 이전에 받았던 응답을 저장 후, 매번 요청할시 저장해놓은 응답재사용 반환하면 되지 않을까?
      1. HTTP Cache 중 Private (웹 브라우저 사이드 = 클라이언트 사이드)
  • 웹 서버 : 웹 페이지 로드 응답이 똑같다면, 웹 서버는 매번 웹 브라우저에게 만들어 반환할 필요가 없다.
    • 이전에 반환한 응답을 저장 후, 매번 요청받을시 저장해놓은 응답재사용 반환하면 되지 않을까?
      1. HTTP Cache 중 Shared (프록시 = CDN or Forward/Reverse Proxy)
      2. API Server 자체 Cache (서버 사이드 = Local or Global)

웹 서버 입장에서..

  • 웹 서버 부하 완화
    • 반복 연산 감소 : 웹 서버가 동적 웹 페이지를 생성하는 연산을 하지 않아도 된다 ← 캐시가 반환
    • 트래픽 분산 : 웹 서버가 모든 요청 트래픽을 받아내지 않아도 된다 ← 캐시가 일부 트래픽 분담
      • 부분 DDoS 방어

웹 브라우저 입장에서..

  • 네트워크 트래픽 감소 (레이턴시 및 네트워크 대역폭 사용 감소)
  • 유저 경험 증진

HTTP Cache 종류

임시 저장 데이터를 누가 필요로 하는가? 특정된 한명인가, 불특정 다수인가?

  • A. Private : 임시 중간 저장소가 웹 브라우저 안에 있다면, 해당 웹 브라우저 유저 한명만을 위한것
    • 웹 브라우저에 위치
      • 브라우저 캐시 : 웹 서버가 HTTP Cache 헤더 (Cache-control) 를 통한 제어 (웹 브라우저에 저장하라)
      • 심화 : 서비스 개발자가 Service Worker (Cache API) 활용하여 오프라인 시 웹 페이지 렌더링 가능
  • B. Shared : 임시 중간 저장소가 웹 브라우저와 웹 서버 사이에 있다면, 모든 웹 브라우저 유저 다수를 위한것

서버 캐시 : HTTP Cache 가 아닌 웹 서버에서 사용하는 캐시

  • 로컬 캐시 : LRU-Cache, Memcache, Ehcache
  • 글로벌 캐시 : Redis (캐시 서버, 데이터베이스에 가까운 사용)

HTTP Cache 동작 : 재검증을 통한 캐시값의 준실시간성 보장

HTTP Cache 동작 과정

  • 준실시간 : 캐시해놓은 데이터가 너무 오래된 데이터가 되지 않도록 특정 주기에 따라 재검증을 해주어야한다.
  • 재검증 : 캐시한 데이터의 원본 주인인 웹 서버가 설정한 특정 주기에 따라, 캐시한 데이터가 오래됐는지 검증
    • 검증 방법 : 조건부 요청 사용 = 재검증 기준이 되는 값을 서버에게 보낸다.
      • 심화 : 우리가 마주할 조건부 요청 종류 2개 1. HTTP Cache 재검증 2. CORS 요청 가능여부 확인
    1. 재검증 주기 : 캐시해놓은 데이터를 얼마 간격으로 재검증할지 특정 주기 (예, 1년마다)
      • 개발자들은 데이터의 갱신 특성에 따라 주기 설정 : 자주 바뀌는 데이터? or 잘 안바뀌는 데이터?
        • 주기가 너무 길어도 안되고 : (두부받고 1년 뒤) “엄마, 이거 먹어도 돼?” → “미친놈아”
        • 주기가 너무 짧아도 안된다 : (두부받을때 매번) “엄마, 이거 먹어도 돼?” → “그만 좀 물어봐”
    2. 재검증 기준 : 캐시해놓은 데이터가 오래됐는지 여부를 원본 주인인 웹 서버가 판단하기 위한 기준 근거
      • 수정일 : Last-Modified
      • 고유값 : ETag (Entity Tag, ETag 값으로 가장 많이 쓰이는것이 Hash-based)

304 Not Modified

캐시가 유효한 지 = 원본이 유효한 지 확인하는 과정에서, 바뀐 것이 없을 때

수정일 기반, 고유값 기반 재검증 및 ETag

Last-Modified (수정일)ETag (고유값)

| 낮은 정확도

  • 파일이 수정되지 않았는데 수정일이 변경되는 경우
  • 텍스트 파일 수정 후, 다시 원상복구한 경우 수정일만 변경 | 높은 정확도
  • 그렇기에 사실 Last-Modified 보다 ETag 사용이 좋다.
  • 다만, HTTP 1.0 혹은 1.1 호환성을 위해 둘 다 사용하는편 |
    | 검사 방법
  • If-Modified-Since : 바뀌었어?
  • If-Unmodified-Since : 안바뀌었어? | 검사 방법
  • If-None-Match : 바뀌었어?
  • If-Match : 안바뀌었어? |

웹 서버가 해당 헤더를 주었다면 Last-Modified : 전송 Resource 의 마지막 수정일

캐시가 유효한지 여부(= 원본이 바뀌었는지 여부)를 시간을 기반으로 판단한다

재검증 시 캐시 소유자 (웹 브라우저) : If-Modified-Since (바뀌었어?) (GET, HEAD)

  • 서버 답변 : (바뀌었어) : 200 Resource Cache + 새 응답(새로운 캐시)
  • 서버 답변 : 아니 (안바뀌었어) : 304 Not Changed

재검증 시 캐시 소유자 (웹 브라우저) : If-Unmodified-Since (안바뀌었어?) (POST 서버 상태 변경 Method)

  • 서버 답변 : (안바뀌었어) : 2XX 성공 응답 (200 OK, 204 No Content, 206 Partial Content 등)
  • 서버 답변 : 아니 (바뀌었어) : 412 Precondition Failed (조건부 요청에 대한 False 부정 응답)

웹 서버가 해당 헤더를 주었다면 Etag : 전송 Resource 의 고유값(해시, ID)

캐시가 유효한지 여부(= 원본이 바뀌었는지 여부)를 고유값(해시, ID)을 기반으로 판단한다

재검증 시 캐시 소유자 (웹 브라우저) : If-None-Match (달라? = 바뀌었어?)

  • 서버 답변 : (바뀌었어) : 200 Resource Cache + 새 응답(새로운 캐시)
  • 서버 답변 : 아니 (안바뀌었어) : 304 Not Changed (GET, HEAD)
      • 412 Precondition Failed (POST 서버 상태 변경 Method)

재검증 시 캐시 소유자 (웹 브라우저) : If-Match (같아? = 안바뀌었어?)

  • 서버 답변 : (안바뀌었어) : 2XX 성공 응답 (200 OK, 204 No Content, 206 Partial Content 등)
  • 서버 답변 : 아니 (바뀌었어) : 412 Precondition Failed (조건부 요청에 대한 False 부정 응답)

Hash 및 HMAC

HMAC (Hash-based Message Authentication Code) : 고유성 검증을 위한 Hash 활용의 다른 예

본 예시는 파일 다운로드의 예시지만, 파일을 JSON 으로 바꾸면 Open API 예시가 된다.

  • HMAC 은 다음과 같은 상황에서 사용
    • 다운로드 받은 파일이 변조되었는지 알기 위해
    • (Open) API 를 통해 받은 결과값이 변조되었는지 알기 위해
  • HMAC 을 통해 변조되었는지 여부 판단하는 방법
    • 파일을 다운받거나 혹은 API 결과와 함께
    • 동시에, 서버가 파일 혹은 API 결과계산한 Hash 값 을 함께 받음
  • 받은 파일API 결과 에 대해 클라이언트와 서버가 미리 공유한 키 값 으로 Hash 값 생성
    • 생성된 Hash 값 과 앞서 받은 Hash 값 과 비교
    • 두 값이 같다면위조되지 않은 파일 혹은 API 결과라고 인지

HTTP Cache 사용법 : Cache-control 헤더를 통한 세부 설정

HTTP Cache 의 캐시 저장 여부 옵션

  • no-store : 캐시 안함
  • no-cache : 캐시 함. 단, 매번 재검증 후 사용 (패킷 경량화) ← 헷갈리지 말것! 캐시안하는게 아님
    • 캐시 데이터 쓰기전에 꼭 나한테 재검증해야해 = 나한테 검사받아 = 경량화된 요청-응답

HTTP Cache 의 캐시 저장 장소 옵션

  • public : Private(웹 브라우저) + Shared(프록시) 모두에 저장 ← 헷갈리지 말것! 브라우저에도 저장
  • private : Private(웹 브라우저) 에만 저장

HTTP Cache 의 캐시 재검증 주기 옵션

  • max-age : Expires(유효시간)으로 변환 (기존 Expires 가 있다면 덮어쓴다)
    • *이해를 돕기위한 연습 문제 : max-age=0 는 무엇과 같은 의미일까요? no-cache = 매번 재검증*
  • s-maxage : 프록시 캐시에만 적용되는 유효기간
    • *이해를 돕기위한 연습 문제 : s-maxage=31536000(1년), max-age=0 는 무엇을 의미할까요?*
      • 웹 브라우저는 계속 CDN 에게 재검증을 수행, CDN 은 1년을 주기로 본 웹 서버에게 재검증
      • 웹 브라우저는 CDN 이 자체적으로 Invalidation(무효화)하지 않는한 1년 동안 같은 데이터만

HTTP Cache 의 캐시 재검증 강제 옵션

  • must-revalidate : 재검증 시 무조건 서버를 통해 재검증 된 값만 보겠다는 뜻
    • 서버와의 접속 문제로 재검증이 실패한 경우 기본 행동은 그냥 기존 캐시되어있는 데이터를 반환
      • 하지만, must-revalidate 가 활성화되어있다면 504 에러 발생 = 웹 서버가 연락이 안돼요!
  • proxy-revalidate : 프록시 캐시에 적용되는 must-revalidate 옵션

HTTP Cache 에서 Revalidate

“재검증 시 꼭 재검증이 제대로되어야해!”

SWR(stale-while-revalidate) = 캐시의 즉시성과 최신성을 한번에

HTTP Cache 제어 중 SWR (stale-while-revalidate) 확장 디렉티브 전략

  • 현재에(당장에) 캐싱된 컨텐츠를 즉시 로드하는 즉시성 (Stale 이더라도)
  • 미래에 업데이트된 캐싱 컨텐츠가 사용될 수 있도록 보장하는 최신성
  • 60초 이내에 요청이 오는 경우 (stale-while-revalidate = 60)
    • 재검증 요청을 동시에 하면서 오래된 캐시(Stale) 를 반환


  • 0-1 초 (신선 = 즉시성) ⇒ 캐싱된 응답을 “재검증” 없이 바로 반환

  • 1-60 초 (오래되었지만 반환과 동시 재검증) ⇒ 캐싱된 응답을 바로 반환 + “재검증” 요청 (백그라운드)

  • 60+ 초 (재검증 = 최신성) ⇒ 캐싱된 응답을 사용하지 않음 + 서버에 요청보내어 응답 캐싱 및 반환

서버 부하 완화 및 보안(요청/응답 변조)을 위한 Proxy

Proxy의 정의 및 사용 이유

: 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램

  • 보안 : IP 숨기기 혹은 프록시 서버를 방화벽으로 사용하기도 한다(프록시 방화벽)
  • 속도(캐시) : 동일 요청이 들어오면 서버에 따로 접속할 필요가 없이 저장된 Cache 자원을 반환
    • 전송 시간 절약, 외부 트래픽을 줄여 네트워크 병목 현상도 방지 = 이는 서비스의 속도를 높여준다.
  • ACL : 사이트 접근 범위 정책 정의 (Proxy Server 에 접속할 수 있는 범위를 설정하는 옵션)
  • Log / Audit : 리포트, 모니터링 (회사 내 직원의 인터넷/인트라넷 사용을 레포팅)
  • 지역 네트워크 제한 우회 : 한국에서는 접속이 제한이 되는 사이트 (IP 검사로 한국에서의 접속임을 감지)
    • 이런 경우 프록시 서버를 사용하면 접속을 다른나라로 우회

WAF (Web Application Firewall) & Rate Limiting

  • Rate Limiting : 짧은 시간(예, 1초) 내 너무 많은 요청이 오는걸 막기위한 정책
    • 참고 : WS 나 WAS 같은 원 서버에서도 적용 가능
  • WAF (Web Application Firewall)
    • Honeypot 에 저장된 악성 IP 리스트 활용한 블럭
    • Custom IP 추가 가능 (예, 악성 크롤링 봇 블럭)

Forward Proxy : 웹 클라이언트 보안 및 접근 제어 (은닉)

요청 보내는 측 : 클라이언트 (웹 브라우저) 측에 위치하며, 요청에 대한 세부적 추가 작업을 제공한다.

  • 앞서 배웠던 ISP(Internet Service Provider)Forward Proxy
  1. 라이언트 은닉 : IP 변환을 통해 원 요청자 은닉
    • 우회 (Bypass) : 특정 클라이언트 IP 가 블락되어있다면, 그걸 피해서 접속하기 위해 IP 감춤
  2. 클라이언트 접근 제어 : 특정 IP 혹은 웹 페이지에 대한 접근 금지
  3. 캐싱 : 클라이언트가 받을 응답을 중간에 임시 저장 (개인이 소비하는 입장에서)

Reverse Proxy : 웹 서버 부하 완화 및 보안 (분산)

요청을 받는 측 : 웹 서버 측에 위치하며, 요청에 대한 세부적 추가 작업을 제공한다.


  1. 요청 전달 : URL/I Mapping (URI 기반 Routing), 로드 밸런싱 (요청 분산)
    • 로드 밸런싱 (요청 분산) = 웹 서버 부하 완화
    • 웹 서버 수 동적으로 늘리기 → SRE 의 업무 (고가용성)
  2. 요청 변환 : Header 세팅 (예, X-FORWARDED-BY 로 근원 클라이언트 IP 를 서버에게 전달)
    • X-FORWARDED-BY : 123, 456, 789 → 가장 마지막에 있는게 최초 호출자
  3. 서버 은닉 : 서버 고유의 IP 가 외부로 노출되지 않음
  4. 서버 접근 제어 (요청 필터)
    • DDoS 방지 : Traffic 제어
      • Rate Limiting : 짧은 시간(예, 1초) 내 너무 많은 요청이 오는걸 막기위한 정책
        • 참고 : WS 나 WAS 같은 원 서버에서도 적용 가능
      • WAF (Web Application Firewall)
        • Honeypot 에 저장된 악성 IP 리스트 활용한 블럭
        • Custom IP 추가 가능 (예, 악성 크롤링 봇 블럭)
    • Response Max Size 세팅 : 너무 큰 파일을 반환하는 경우 블락 (Nginx 설정)
    • Timeout 세팅 (Nginx 설정)
  5. 보안 : HTTPS
    • 모든 서버가 Private Key 를 가지고 있어야하는 단점
    • 한 서버(Reverse Proxy)가 Private Key 를 가지고 있으면 관리 및 인증 간편
    • 캐싱 : 클라이언트가 자주하는 요청에 대한 응답을 중간에 임시 저장 (다수에 제공하는 관점)

Load Balancer 사용 이유 및 장점

L2 Reverse Proxy : Load Balancer → 대량 트래픽에 의한 서버 부담을 분산하기 위해

  • 대량의 트래픽이 한개의 웹 서버에 집중되는 경우
    • 한개의 웹 서버가 트래픽을 감당하지 못해 터져버린다 → 수직적 확장 혹은 수평적 확장이 필요
  1. 새 버전의 웹 어플리케이션을 배포 시
    • 새로운 웹 서버에 배포하는 경우 IP 가 변경
    • 기존의 웹 서버에 배포를 하더라도 기존 버전을 정지하고 새 버전을 구동하는 동안 유저는 사용하지 못함

트래픽 분산뿐만 아니라, 트래픽이 급증하거나 급감하는 경우 서버의 수를 동적으로 제어하여 고가용성 제공

로드밸런서를 웹 서버의 앞단에 두고, IP 를 부여한 뒤 웹 클라이언트가 해당 로드밸런서를 호출하게 하면

  • 로드밸런서는 앞단의 모든 웹 클라이언트의 요청을 받아, 뒷단의 모든 웹 서버에게 요청을 분산합니다.
    • 배포 이슈 해결 : 클라이언트는 고정된 IP 의 로드밸런서만 호출하기에 웹 서버가 몇개든 죽든말든 노상관
    • 트래픽 이슈 해결 : 아무리 많은 요청이 들어와도 로드밸런서 뒷단에 서버 수만 늘리면된다 (수평적 확장)

L1 Reverse Proxy : CDN (Contents Delivery Network)

Proxy캐싱 + 요청에 대한 세부적 추가 작업 를 위해 사용

  • 캐싱 : 요청에 따른 응답을 중간 저장해놓은 뒤 동일 요청 시 저장값 반환
  • 요청에 대한 세부적 추가 작업 : 요청 변환, 필터 등의 추가 작업 수행

그렇다면 CDN 은 어떤 목적을 위해 사용하는가? = 캐싱 + 지역성 해결 을 위해 사용

  • 캐싱 : 요청에 따른 응답을 중간 저장해놓은 뒤 동일 요청 시 저장값 반환
    • 원본 데이터를 가진 웹 서버에 문제가 생기면 CDN 가 대신 응답을 반환하여 고가용성 보장
      • CDN : 고가용성을 보장해주는 버퍼의 역할
    • 원본 데이터를 가진 웹 서버에 DDoS 공격이 가해지는것을 CDN 이 대신 방어
  • 지역성 해결 : HTTP Resource 제공 서버와 클라이언트가 멀리 떨어진 경우 클라이언트에 가까운곳에 저장
    • 한국 웹 브라우저에서 미국 웹 서버로부터 응답을 받으려면 긴 응답시간
    • 전세계적으로 캐시 서버를 곳곳에 두어 캐시 서버 내 응답 데이터를 캐싱(저장)한다면 속도 개선
    • 캐시 서버로 동작하는 만큼 원 서버에 문제가 생기면 CDN 이 False Tolerance 장애 허용을 해주기도 함

CDN의 정의 및 역할, 사용 예시

  • 고가용성을 보장해주는 버퍼의 역할
    • 캐싱 + 지역성 해결을 위해 사용
      • ex) 한국에 있는 사용자가 아르헨티나에 원본 서버를 가진 웹 사이트의 고양이 사진을 보고싶을 때, 한국에 위치한 엣지 서버에서 PoP(Points of presence)를 통해 사용자에게 보내는 방식
  • CDN의 세 가지 주요 구성 요소
    • 원본 서버 텍스트, 이미지, 비디오 등과 같은 실제 웹사이트 콘텐츠를 호스팅하는 원본 서버
    • 엣지 서버 CDN은 서버를 지리적으로 분산하여 최종 사용자와 더 가까운 곳에 배치 웹 콘텐츠를 저장하여 사용자에게 더 빠르게 전송
    • PoP(Points of presence) 엣지 서버를 포함하는 데이터 센터 → 교통 허브와 같은 역할 콘텐츠는 사용자와 더 가까운 다른 엣지 서버 위치로 이동하기 전에 이러한 데이터 센터에서 중지
profile
(와.. 정말 Chill하다..)

0개의 댓글