캐시(cache), 세션(session)

jaeyong Lee·2024년 8월 13일

Backend Development

목록 보기
6/7
post-thumbnail

20250117 수정)

캐시

클라이언트 측 캐시

저장 위치: 사용자의 로컬 메모리(브라우저).
저장 대상: 접속한 웹페이지의 정적 리소스(HTML, CSS, JS, 이미지 등).
목적: 빠른 로드와 네트워크 트래픽 감소.

서버 측 캐시

저장 위치: 서버의 메모리(RAM).
저장 대상: 자주 요청되는 데이터(쿼리 결과, 계산된 데이터 등).
목적: 서버 성능 향상과 응답 시간 단축.

세션

세션도 브라우저에 사용자 관련 정보 저장하지 않나?

위 내용은 맞지 않다고 생각
세션은 서버에 사용자 인증 및 인가와 관련된 정보를 저장

즉 세션은 특정 사용자의 상호작용을 관리하고 로그인 상태나 사용자 맞춤 정보를 저장하는데 중점
+) 인가를 다루는 또다른 방법 -> JWT

정리

캐시는 정적인 데이터 클라이언트 측 에서 일시적으로 저장하는거고 세션은 사용자의 정보를 서버측에 저장해서 적절할 때 꺼내온다.

session 실제 예시

https://velog.io/@lee41180612/Session
위 링크 참조

cache 예시

캐시는 브라우저가 저장하는 것이기 때문에 서버에서 지시하지 않아도 웹 리소스를 캐시한다.
하지만 이것은 제한적 이므로 세밀한 제어는 서버에서 가능하다.

성능 최적화 : 웹페이지 로딩속도를 크게 개선가능

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

import java.util.concurrent.TimeUnit;

@RestController
public class PerformanceController {

    @GetMapping("/")
    //중요한 정적 리소스를 브라우저에 1시간 동안 캐시
    //태그로 변경 여부를 확인해서 불필요한 작업을 줄인다 
    public ResponseEntity<String> getPerformanceOptimizedResource() {
        CacheControl cacheControl = CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic();
        
        return ResponseEntity.ok()
                             .cacheControl(cacheControl)
                             .body("This resource is cached for 1 hour");
    }
}

유효성 제어 : 웹이 자주 업데이트 되는 경우 서버측에서 캐시 유효성을 정밀하게 제어할 수 있다.

import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

@RestController
public class ETagController {

    private static final String E_TAG = "12345"; // 고정된 ETag 값

    @GetMapping("/etag")
    public ResponseEntity<String> getETagResource(@RequestHeader(value = HttpHeaders.IF_NONE_MATCH, required = false) String ifNoneMatch) {
        if (Objects.equals(ifNoneMatch, E_TAG)) {
            return ResponseEntity.status(304).build(); // 변경되지 않았으므로 304 Not Modified
        }

        return ResponseEntity.ok()
                             .eTag(E_TAG)
                             .body("This is the latest resource with ETag");
    }
}

보안 : 민감한 데이터는 브라우저가 캐시하지 못하게 설정 가능

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

@RestController
public class SecurityController {

    @GetMapping("/secure-data")
    public ResponseEntity<String> getSensitiveData() {
        CacheControl cacheControl = CacheControl.noStore(); // 캐시 금지

        return ResponseEntity.ok()
                             .cacheControl(cacheControl)
                             .body("This sensitive data should not be cached");
    }
}

위와 같은 요인들로 서버측에서 캐시설정 해주는게 좋다.

정리, 나의 생각

서버에서 캐시를 세밀하게 구현할 수도 있는 것을 다시 상기했다. 앞으로 기회가 되면 서버에서 직접 캐시를 활용해보고 싶다는 생각이 들었고, 브라우저랑 연관이 깊어서 프론트엔드에서도 캐시를 적용할 수 있겠다는 가능성도 보았다.

세션이랑 JWT를 묶어서 인가라는 큰 개념으로 이해할 수 있게 되었다는 점도 내가 성장한 부분이라고 느꼈다. 세션과 JWT의 차이랑 역할을 정리하면서, 실제로 이를 시스템 설계에 어떻게 활용할지 선택도 가능해졌다.

이번 글을 수정하면서 느낀건 하다보니 내가 했던 모든 것들이 연결되어 계속 확장되어가고있었다는 것이다. 이렇게 계속 배워나가며 성장하고 싶다.

0개의 댓글