๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Cache-Control

์‹œํ๋ฆฌํ‹ฐ์ง€ํ˜ธ 2024. 11. 10.

์š”์ฆ˜ ํšŒ์‚ฌ์—์„œ ์—ฌ๋Ÿฌ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๋‹ค๋ณด๋‹ˆ "Cache-Control" ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.

 

์‹ค์ œ๋กœ ๋„ค์ด๋ฒ„ ๋Œ€ํ‘œํŽ˜์ด์ง€์—์„œ ๋„คํŠธ์›Œํฌ ์ฐฝ์„ ๋ณด๋ฉด ์š”์ฒญ, ์‘๋‹ต๊ฐ’์— "Cache-Control"  ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๊ณ  value ๊ฐ’์œผ๋ฃŒ no-cache, no-store, must-revalidate ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด ์ •ํ™•ํ•˜๊ฒŒ "Cache-Control" ์ด ๋ฌด์—‡์ผ๊นŒ? ์•Œ์•„๋ณด์ž

 


 

Cache-Control ์ด๋ž€? 

Cache-Control์€ ์›น ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„ ๊ฐ„์— ์บ์‹ฑ ์ •์ฑ…์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ HTTP ํ—ค๋”์ด๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์ค„์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

 

 

์ฃผ์š” Cache-Control ๋””๋ ‰ํ‹ฐ๋ธŒ

 

  • no-cache: ํ•ญ์ƒ ์„œ๋ฒ„์—์„œ ์ตœ์‹  ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ๊ฐ•์ œํ•œ๋‹ค.
  • no-store : ๋ฆฌ์†Œ์Šค๋ฅผ ์ „ํ˜€ ์บ์‹œํ•˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•œ๋‹ค. ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ์— ์ฃผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
  • public : ๋ฆฌ์†Œ์Šค๋ฅผ ๋ชจ๋“  ์บ์‹œ(๊ณต์šฉ, ๊ฐœ์ธ)์—์„œ ์บ์‹œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•œ๋‹ค.
  • private : ํŠน์ • ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ๊ฐœ์ธ ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ์บ์‹œํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œํ•œํ•œ๋‹ค.
  • max-age : ์บ์‹œ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ง€์ •๋œ ์‹œ๊ฐ„(์ดˆ) ๋™์•ˆ ์œ ํšจํ•˜๊ฒŒ ์„ค์ •ํ•œ๋‹ค.
  • s-maxage : ํ”„๋ก์‹œ ์„œ๋ฒ„ ์บ์‹œ์—๋งŒ ์ ์šฉ๋˜๋Š” max-age ๋กœ, CDN ๋˜๋Š” ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ์— ์œ ์šฉํ•˜๋‹ค.
  • must-revalidate : ๋งŒ๋ฃŒ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ์„œ๋ฒ„์—์„œ ์ƒˆ๋กœ ๊ฐ€์ ธ์˜ค๋„๋ก ๊ฐ•์ œํ•œ๋‹ค.

 

Spring์—์„œ Cache-Control ์‚ฌ์šฉํ•˜๊ธฐ

Spring์—์„œ๋Š” @GetMapping๊ณผ ํ•จ๊ป˜ CacheControl์„ ์„ค์ •ํ•˜์—ฌ ํŠน์ • ์—”๋“œํฌ์ธํŠธ์˜ ์บ์‹ฑ ๋™์ž‘์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์‹œ์ฝ”๋“œ

๋‹ค์Œ์€ Cache-Control ์„ ์„ค์ •ํ•˜์—ฌ max-age ๊ฐ€ 60์ดˆ์ธ ์บ์‹œ ์ •์ฑ…๊ณผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•ญ์ƒ ์„œ๋ฒ„์—์„œ ์ตœ์‹  ๋ฒ„์ „์„ ๊ฐ€์ ธ์˜ค๋Š” ์ •์ฑ…์„ ์ ์šฉํ•˜๋Š” ์˜ˆ์ œ

 

import org.springframework.http.CacheControl;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api")
public class ExampleController {

    @GetMapping("/cache")
    public ResponseEntity<String> cacheExample() {
        return ResponseEntity.ok()
                .cacheControl(CacheControl.maxAge(60, TimeUnit.SECONDS))  // ์บ์‹œ ์œ ํšจ ์‹œ๊ฐ„ ์„ค์ •
                .body("This response is cached for 60 seconds.");
    }

    @GetMapping("/no-cache")
    public ResponseEntity<String> noCacheExample() {
        return ResponseEntity.ok()
                .cacheControl(CacheControl.noCache())  // ํ•ญ์ƒ ์ตœ์‹  ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ์„ค์ •
                .body("This response is not cached.");
    }
}

 

์„ค๋ช… 

  • CacheControl.maxAge(60, TimeUnit.SECONDS) : ์บ์‹œ๋ฅผ 60์ดˆ ๋™์•ˆ ์œ ํšจํ•˜๊ฒŒ ์œ ์ง€ํ•œ๋‹ค.
  • CacheControl.noCache() : ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•ญ์ƒ ์„œ๋ฒ„์—์„œ ์ตœ์‹  ๋ฒ„์ „์„ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•œ๋‹ค.

 

Cache-Control ์‚ฌ์šฉ์˜ ์žฅ์ 

1. ์„œ๋ฒ„ ๊ฐ„์˜ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ์กฐ์ ˆํ•˜์—ฌ ์„œ๋ฒ„ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

2. ๋™์ ์œผ๋กœ ๋ณ€ํ™”ํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

๋Œ“๊ธ€