[λ„€νŠΈμ›Œν¬] πŸ“š (WEB) μΊμ‹œ μ΄ν•΄ν•˜κΈ°

ν—ŒμΉ˜Β·2022λ…„ 9μ›” 25일
1

λ„€νŠΈμ›Œν¬

λͺ©λ‘ 보기
4/4
post-thumbnail

ν•΄λ‹Ή 글은 CS μŠ€ν„°λ””μ—μ„œ κ³΅λΆ€ν•œ λ‚΄μš©μ„ 기반으둜 μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

0.λ“€μ–΄κ°€λ©°

μ΄λ²ˆμ— μš°ν…Œμ½” λ―Έμ…˜μ„ μˆ˜ν–‰ν•˜λ©° μΊμ‹œ κ΄€λ ¨ ν•™μŠ΅ν…ŒμŠ€νŠΈλ₯Ό μ§„ν–‰ν–ˆλ‹€.

μΊμ‹œκ°€ 무엇인지, μ–΄λ–€ μ‹μœΌλ‘œ λ™μž‘ν•˜λŠ” 지에 λŒ€ν•΄ μ–•κ²Œλ§Œ μ•Œκ³  μžˆλ‹¨ 것을 μ•Œμ•˜λ‹€.

μ²˜μŒμ—” μΊμ‹œκ°€ μ›Ή μΊμ‹œλ§Œ μžˆλŠ” 쀄 μ•Œκ³ , μŠ€ν„°λ”” 주제 μ„ μ • μ‹œ μΊμ‹œλ₯Ό λ„€νŠΈμ›Œν¬ λΆ„μ•Ό μ•ˆμ—λ§Œ λ„£μ—ˆλ‹€!

μ°Ύμ•„λ³΄λ‹ˆ κ·Έ μ–΄λ–€ 곳이든(λ©”λͺ¨λ¦¬λ“ , L1~L3λ“ !) 데이터 접근을 μœ„ν•΄ ν• λ‹Ήν•΄λ‘λŠ” μž₯μ†Œμ˜€λ‹€.

μ΄λ²ˆμ—” 그쀑 μ›ΉμΊμ‹œλ‘œ ν•œμ •μ§€μ–΄ 아티클을 찾아보며 κ³΅λΆ€ν•΄λ³΄μ•˜λ‹€.


πŸ’Ά (μ›Ή) μΊμ‹œ

μΊμ‹œ λŠ” λ°μ΄ν„°λ‚˜ 값을 μž„μ‹œλ‘œ λ³΅μ‚¬ν•΄λ‘λŠ” μž„μ‹œ μž₯μ†Œμ΄λ‹€. μΊμ‹œμ˜ μ ‘κ·Ό μ‹œκ°„μ— λΉ„ν•΄ μ›λž˜ 데이터λ₯Ό μ ‘κ·Όν•˜λŠ” μ‹œκ°„μ΄ 였래 κ±Έλ¦¬λŠ” κ²½μš°λ‚˜ 값을 λ‹€μ‹œ κ³„μ‚°ν•˜λŠ” μ‹œκ°„μ„ μ ˆμ•½ν•˜κ³  싢은 κ²½μš°μ— μ‚¬μš©ν•œλ‹€.

캐싱

주어진 λ¦¬μ†ŒμŠ€μ˜ 볡사본을 μΊμ‹œμ— μ €μž₯ν•˜κ³  μžˆλ‹€κ°€, μš”μ²­ μ‹œ 그것을 μ œκ³΅ν•˜λŠ” κΈ°μˆ μ΄λ‹€.

μΊμ‹±μ˜ μž₯점

ν΄λΌμ΄μ–ΈνŠΈμ˜ 경우, 캐싱을 톡해 μ›Ήμ‚¬μ΄νŠΈκ°€ μ’€ 더 λΉ λ₯΄κ²Œ λ°˜μ‘ν•˜λ„λ‘ λ§Œλ“€ 수 μžˆλ‹€. 즉 μ„±λŠ₯이 ν–₯μƒλœλ‹€.

μ„œλ²„ μ—­μ‹œ 기쑴에 였던 데이터가 μ˜€μ§€ μ•Šκ²Œ λ˜λ‹ˆ μš”μ²­ λΆ€ν•˜λ₯Ό 쀄일 수 μžˆλ‹€.

μΏ ν‚€ vs μΊμ‹œ

μ •μ˜

λ‘˜λ‹€ μ›Ή λΈŒλΌμš°μ € μƒμ—μ„œ μ €μž₯λ˜λŠ” μ •λ³΄μ΄μ§€λ§Œ κ·Έ μ“°μž„μƒˆκ°€ λ‹€λ₯΄λ‹€.

μΏ ν‚€λŠ” μ‚¬μš©μž 인증 정보λ₯Ό μ €μž₯ν•˜λŠ” μš©λ„μ΄λ‹€. λ‹€μ‹œ μ‚¬μš©μž 재인증(둜그인 λ“±)을 κ±°μΉ˜μ§€ μ•Šμ•„λ„ λœλ‹€λŠ” νŽΈλ¦¬ν•¨ λ•Œλ¬Έμ— μ‚¬μš©λœλ‹€.

μΊμ‹œλŠ” μ›Ήμ‚¬μ΄νŠΈκ°€ λ‹€μ‹œ μ„œλ²„λ‘œ μš”μ²­μ„ 보내지 μ•Šμ•„λ„ λ˜λ‹ˆ μ„±λŠ₯상 이점이 μžˆλ‹€. 주둜 JS, CSS λ“±μ˜ νŒŒμΌλ“€μ΄ μΊμ‹±λœλ‹€.

πŸš€ HTTP μΊμ‹œ

μ’…λ₯˜

Private Cache

μ›Ή λΈŒλΌμš°μ €μ— μ €μž₯λ˜λŠ” μΊμ‹œ. ν•œλͺ…μ˜ μ‚¬μš©μžλ§Œ μ‚¬μš©ν•œλ‹€.

λ‹€λ₯Έ μ‚¬λžŒμ€ μ ‘κ·Όν•  수 μ—†λ‹€.

Shared Cache

μ›Ή λΈŒλΌμš°μ €μ™€ μ„œλ²„ μ‚¬μ΄μ—μ„œ λ™μž‘ν•œλ‹€. ν•œλͺ… μ΄μƒμ˜ μ‚¬μš©μžκ°€ μž¬μ‚¬μš©ν•  수 μžˆλ‹€.

Proxy Cache와 Managed Cache둜 λ‚˜λ‰œλ‹€.

  1. Proxy CacheλŠ” ν¬μ›Œλ“œ ν”„λ‘μ‹œμ—μ„œ λ™μž‘ν•˜λŠ” μΊμ‹œμ΄λ‹€.
  2. Managed CacheλŠ” AWSλ‚˜ Cloudfront λ“± CDN μ„œλΉ„μŠ€, λ¦¬λ²„μŠ€ ν”„λ‘μ‹œμ—μ„œ λ™μž‘ν•˜λŠ” μΊμ‹œμ΄λ‹€. 이런 μΊμ‹œλ“€μ€ κ΄€λ¦¬μž νŒ¨λ„μ΄λ‚˜ λ¦¬λ²„μŠ€ ν”„λ‘μ‹œ μ„€μ •μœΌλ‘œ 관리 κ°€λŠ₯ν•΄ Managed Cache(κ΄€λ¦¬λ˜λŠ” μΊμ‹œ)라고 λΆˆλ¦°λ‹€.

A shared cache must not use a cached response to a request with an Authorization header field (Section 4.2 of [RFC7235]) to satisfy any subsequent request unless a cache directive that allows such responses to be stored is present in the response.
RFC7234

μ„œλ²„ 응닡 헀더 쀑 Authorization이 ν¬ν•¨λ˜μ–΄ μžˆμ„ μ‹œ Shared Cache에 μ €μž₯λ˜μ§€ μ•ŠλŠ”λ‹€.

Cache-Control

캐싱 μ œμ–΄λ₯Ό μœ„ν•΄ Cache-Control μ΄λΌλŠ” HTTP 헀더λ₯Ό μ“΄λ‹€.

ν•΄λ‹Ή 헀더가 없을 μ‹œ νœ΄λ¦¬μŠ€ν‹± 캐싱(암묡적 캐싱)이 일어날 수 μžˆλ‹€.

μΊμ‹œ μ—¬λΆ€

μΊμ‹±ν•˜μ§€ μ•Šμ„ μ‹œ no-store을 μ‚¬μš©ν•œλ‹€. μ„œλ²„ 응닡을 μ „ν˜€ μ €μž₯ν•˜μ§€ μ•ŠλŠ”λ‹€.

μΊμ‹±ν•˜μ§€λ§Œ μž¬κ²€μ¦, 즉 μœ νš¨μ„± 확인을 ν•˜κ³  싢을 땐 no-cacheλ₯Ό μ‚¬μš©ν•œλ‹€.

μ›ΉμΊμ‹œ 일관성 기법 쀑 polling-every-time(맀번 μž¬κ²€μ¦-μœ νš¨μ„± 확인) ν˜•νƒœλ₯Ό μ‚¬μš©ν•˜κ²Œ λœλ‹€.

사섀(λΈŒλΌμš°μ €) μΊμ‹œμ™€ 곡유(ν”„λ‘μ‹œ) μΊμ‹œ

public 은 응닡 μ‹œ μ–΄λ–€ μΊμ‹œμ—μ„œ μΊμ‹±λ˜μ–΄λ„ μ’‹λ‹€λŠ” λœ»μ΄λ‹€. 곡유 μΊμ‹œμ— μ €μž₯λ˜μ–΄λ„ μ’‹λ‹€.

private 은 응닡을 단일 μ‚¬μš©μžλ§Œμ„ μœ„ν•΄ μ‚¬μš©ν•΄μ•Ό ν•˜λ©°, 곡유 μΊμ‹œμ— μ €μž₯되면 μ•ˆλœλ‹€λŠ” λœ»μ΄λ‹€.

만료

max-age둜 μΊμ‹œμ˜ μ΅œλŒ€ 수λͺ… 섀정이 κ°€λŠ₯ν•˜λ‹€. λ‹¨μœ„λŠ” β€œμ΄ˆβ€ 이닀.

μΊμ‹œλœ 데이터가 μœ νš¨ν•  땐 fresh(μ‹ μ„ ν•œ)라고,

μΊμ‹œ μ‹œκ°„μ΄ 초과된 경우 stale(μ‹ μ„ ν•˜μ§€ μ•Šμ€)라고 ν•œλ‹€.

μ˜ˆμ „μ—” κ΄€λ ¨ν•΄ Expires 헀더λ₯Ό μΌμ§€λ§Œ, μ§€κΈˆμ€ 잘 쓰지 μ•ŠλŠ”λ‹€.

검증

must-revalidate μ‚¬μš© μ‹œ, 였래된 λ¦¬μ†ŒμŠ€λ₯Ό μ‚¬μš©ν•˜κΈ° μ „ μƒνƒœλ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄ μΊμ‹œ 검증을 μ§„ν–‰ν•˜κ²Œ λœλ‹€.

μ˜ˆμ „μ—” max-age=0κ³Ό ν•¨κ»˜ 이 헀더λ₯Ό μΌμ§€λ§Œ, μ§€κΈˆμ€ no-cache둜 μž¬κ²€μ¦μ„ μ§„ν–‰ν•œλ‹€. max-age=0 이 λ¨Ήνžˆμ§€ μ•ŠλŠ” λΈŒλΌμš°μ €κ°€ μžˆμ–΄μ„œ κ·Έλ ‡λ‹€κ³  ν•œλ‹€.

μΊμ‹œ 검증

μΊμ‹œ μœ νš¨κΈ°κ°„μ΄ 지났을 λ•Œ, μ„œλ²„μ˜ 데이터가 μ—¬μ „νžˆ μΊμ‹±λœ 데이터와 같을 수 μžˆλ‹€.

μ΄λ•Œ νŠΈλž˜ν”½ λ‚­λΉ„λ₯Ό 쀄이기 μœ„ν•΄ μΊμ‹œ 검증 및 쑰건뢀 μš”μ²­μ„ ν•  수 μžˆλ‹€.

보톡 μ‚¬μš©μžκ°€ λ¦¬λ‘œλ“œ λ²„νŠΌμ„ λˆŒλ €μ„ 경우 μ΄‰λ°œλœλ‹€.

no-cacheλ‚˜ must-revalidate μ‚¬μš© μ‹œ, 일반적인 λΈŒλΌμš°μ§• 쀑에도 μ΄‰λ°œλœλ‹€.

μΊμ‹œ 검증을 μœ„ν•œ 두가지 방법이 μžˆλ‹€.

If-Modified-Since(Last-Modified)

λ¦¬μ†ŒμŠ€μ˜ λ§ˆμ§€λ§‰ κ°±μ‹  μ‹œκ°„μœΌλ‘œ 검증함.

첫 μš”μ²­

Last-Modified 헀더엔 μš”μ²­ν•œ λ¦¬μ†ŒμŠ€κ°€ λ§ˆμ§€λ§‰μœΌλ‘œ μˆ˜μ •λœ μΌμžκ°€ λ“€μ–΄κ°„λ‹€. λΈŒλΌμš°μ €λŠ” 이 일자λ₯Ό μ €μž₯ν•œλ‹€.

쑰건뢀 μš”μ²­

이후 μΊμ‹œ 기간이 초과된 μš”μ²­μ„ λ°›μ•˜μ„ μ‹œ, λΈŒλΌμš°μ €λŠ” 이 일자 값을 If-Modified-Since μš”μ²­ 헀더에 λ„£μ–΄ μ„œλ²„λ‘œ μ „λ‹¬ν•œλ‹€.

λ§Œμ•½ 원본 λ¦¬μ†ŒμŠ€μ— 변경사항이 μ—†μœΌλ©΄ 304(Not Modified) μƒνƒœμ½”λ“œλ‘œ μ‘λ‹΅ν•œλ‹€. ν•΄λ‹Ή 응닡엔 λ°”λ””κ°€ λΉ„μ–΄μžˆλ‹€.

변경사항이 μžˆμ„ μ‹œ 200(OK)λ₯Ό μ‘λ‹΅ν•œλ‹€. ν•΄λ‹Ή 응닡엔 μ„œλ²„μ—μ„œ 온 λ°”λ””κ°€ μžˆλ‹€.

If-None-Match(ETag)

λ¦¬μ†ŒμŠ€μ˜ μ‹λ³„μžλ₯Ό κΈ°μ€€μœΌλ‘œ 검증함.

첫 μš”μ²­

졜초 μš”μ²­ μ‹œ ETag 응닡 헀더가 λŒμ•„μ˜¨λ‹€. μš”μ²­ν•œ λ¦¬μ†ŒμŠ€μ˜ ν˜„μž¬ 버전에 λŒ€ν•œ ν•΄μ‹œ μ‹λ³„μžμ΄λ‹€. λΈŒλΌμš°μ €λŠ” 이 값을 μ €μž₯ν•œλ‹€.

쑰건뢀 μš”μ²­

이후 μΊμ‹œ 기간이 초과된 μš”μ²­μ„ λ°›μ•˜μ„ μ‹œ, If-None-Match 헀더에 ν•΄λ‹Ή 값을 λ„£μ–΄ 보낸닀.

이 κ²½μš°μ—λ„ 변경사항이 μ—†μœΌλ©΄ 304 μƒνƒœμ½”λ“œλ‘œ μ‘λ‹΅ν•œλ‹€.

상황에 λ”°λ₯Έ 응닡

Vary ν—€λ”λŠ” 캐싱을 할지 κ²°μ •ν•˜κΈ° μœ„ν•΄, μš”μ²­ 헀더λ₯Ό λŒ€μ‘°ν•˜λŠ” 방식을 κ²°μ •ν•œλ‹€.

μΊμ‹œκ°€ Vary 헀더가 ν¬ν•¨λœ μš”μ²­μ„ μˆ˜μ‹ ν•  경우, Vary에 μ§€μ •λœ λͺ¨λ“  헀더 ν•„λ“œκ°€ μΊμ‹±λœ μ›λž˜ μš”μ²­κ³Ό λŒ€μ‘°λœλ‹€. λ‘˜μ΄ 같지 μ•Šλ‹€λ©΄ μΊμ‹±λœ 응닡을 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€.

VaryλŠ” μ£Όμ˜ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. μΊμ‹œμ˜ 효과λ₯Ό λ–¨μ–΄λœ¨λ¦΄ 수 μžˆλ‹€. 여기에 μ§€μ •λœ 헀더값이 μ—¬λŸ¬κ°€μ§€μΈ 경우, μ •κ·œν™”κ°€ ν•„μš”ν•˜λ‹€.

μ •κ·œν™”

μΊμ‹œ μ„œλ²„λŠ” 기본적으둜 헀더와 헀더 값이 μ •ν™•νžˆ 같은 μš”μ²­λ§Œ λ§€μΉ˜μ‹œν‚¨λ‹€.

Accept-Encoding: gzip,deflate,sdch, 

Accept-Encoding: gzip,deflate, 

Accept-Encoding: gzip

μ›λž˜ μ„œλ²„κ°€ λͺ¨λ“  μš”μ²­μ— λŒ€ν•΄ λ˜‘κ°™μ€ λ¦¬μ†ŒμŠ€(gzip)λ₯Ό 응닡 ν•˜λ”λΌλ„, 각각 λ‹€λ₯Έ μΊμ‹œ μ—”νŠΈλ¦¬κ°€ μƒμ„±λœλ‹€.

// μˆ˜λ„μ½”λ“œ

// Accept-Encoding μ •κ·œν™”
if (req.http.Accept-Encoding) {
  if (req.http.Accept-Encoding ~ "gzip") {
    set req.http.Accept-Encoding = "gzip";
  }
  // 아닐 경우, λ‹€λ₯Έ encoding type듀을 μ²΄ν¬ν•œλ‹€.
else {
  unset req.http.Accept-Encoding;
  }
}

λ”°λΌμ„œ, 이λ₯Ό 막기 μœ„ν•΄ μΊμ‹œ μ„œλ²„λŠ” μš”μ²­μ„ μ „μ²˜λ¦¬ν•΄μ„œ ν•„μš”ν•œ 파일만 μΊμ‹œν•΄μ•Ό ν•œλ‹€.

μΊμ‹œ λ¬΄νš¨ν™”(cache invalidation)

보톡 정적 λ¦¬μ†ŒμŠ€μ˜ 경우 μΊμ‹±ν•œλ‹€. ν•˜μ§€λ§Œ μžλ°”μŠ€ν¬λ¦½νŠΈμ™€ cssλŠ” 개발이 진행됨에 따라 자주 λ³€κ²½λ˜κ³ , μžλ°”μŠ€ν¬λ¦½νŠΈμ™€ CSS λ¦¬μ†ŒμŠ€ 버전이 λ™κΈ°ν™”λ˜μ§€ μ•ŠμœΌλ©΄ 화면이 깨진닀.

μΊμ‹œλŠ” URL을 기반으둜 λ¦¬μ†ŒμŠ€λ₯Ό κ΅¬λΆ„ν•œλ‹€. μ΄λ•Œ μΊμ‹œ λ¬΄νš¨ν™”λ₯Ό ν•˜λŠ” 방법이 μžˆλ‹€. 정적 νŒŒμΌμ— URL에 버전을 μΆ”κ°€ν•΄ μΊμ‹œ λ¬΄νš¨ν™”λ₯Ό ν•œλ‹€. λ¦¬μ†ŒμŠ€κ°€ μ—…λ°μ΄νŠΈ 될 λ•Œλ§ˆλ‹€ URL을 λ³€κ²½ν•˜λŠ” 것이닀.

μž₯점

μΊμ‹œ λ¬΄νš¨ν™”λ₯Ό ν•˜λ©΄ μ΅œλŒ€ν•œ μ˜€λž«λ™μ•ˆ μΊμ‹±ν•˜λ©΄μ„œλ„, μƒˆλ‘œμš΄ λ¦¬μ†ŒμŠ€λ‘œ λ°”λ€” μ‹œ λ°”λ‘œ 바뀐 μΊμ‹œλ₯Ό ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μ œκ³΅ν•  수 μžˆλ‹€.

μ£Όμ˜μ‚¬ν•­

쿼리 λ¬Έμžμ—΄μ€ 캐싱 문제λ₯Ό λ°œμƒμ‹œν‚¨λ‹€?!🀯 일뢀 ν”„λ‘μ‹œ λ˜λŠ” CDN은 쿼리 λ¬Έμžμ—΄μ΄ ν¬ν•¨λœ νŒŒμΌμ„ μΊμ‹œν•  수 μ—†μœΌλ―€λ‘œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€.

파일 μ΄λ¦„μ΄λ‚˜ κ²½λ‘œκ°€ μˆ˜μ •λ˜λ©΄ ν•΄λ‹Ή νŒŒμΌμ„ μ°Έμ‘°ν•˜λŠ” HTML(Main Resource)도 μ—…λ°μ΄νŠΈ ν•΄μ•Ό ν•œλ‹€. λ˜ν•œ HTML νŒŒμΌμ€ λ˜λ„λ‘ μΊμ‹±λ˜μ–΄μ„  μ•ˆλœλ‹€. μΊμ‹±ν•˜κ³  μ‹Άλ‹€λ©΄, ETag 등을 톡해 κ°•μ œ μž¬κ²€μ¦ ν•΄μ€˜μ•Ό ν•œλ‹€.


λŠλ‚€ μ πŸ’¬

κ΄€λ ¨ν•΄ 자료λ₯Ό 찾아보며, 유λͺ… μ‚¬μ΄νŠΈ(ꡬ글, 넀이버 λ“±)의 톡신을 뢄석해봀닀.

생각보닀 MDNμ—μ„œ ꢌμž₯λ˜μ§€ μ•ŠλŠ” 헀더듀이 많이 μ‚¬μš©λ˜κ³  μžˆμ—ˆλ‹€. 특히 Pragma 헀더가 HTTP 1.1μ—μ„œλ„ 많이 λ³΄μ˜€λ‹€. μ™œμΌκΉŒ? μ•ˆμ •μ„± λ•Œλ¬ΈμΌκΉŒ?

λΉ„μŠ·ν•œ μ–˜κΈ°λ‘œ must-revalidate μ—­μ‹œ 자주 λ³΄μ˜€λ‹€. 생각해 λ³΄μ•˜λŠ”λ°, λ ˆκ±°μ‹œμΌ μˆ˜λ„ μžˆμ§€λ§Œ ν˜Έν™˜μ„±μ„ μœ„ν•΄μ„œ κ·ΈλŒ€λ‘œ λ‘” 것일 μˆ˜λ„ μžˆμ„ 것 κ°™λ‹€.

ν˜„μ—…μ—μ„  닡을 찾을 수 μžˆκ² μ§€?πŸ€”

profile
🌱 ν•¨κ»˜ μžλΌλŠ” μ€‘μž…λ‹ˆλ‹€ πŸš€ rerub0831@gmail.com

0개의 λŒ“κΈ€