본문 바로가기

프로그래밍/Spring

[Spring Boot] Session과 Cache의 기본 저장소 !

개발기간이 길진 않지만 개발하며 정말 효울적으로 사용했던게 Session과 Cache라고 생각했습니다. Databased에 저장하려니 너무 개발cost가 많이 들고 파일로 저장하자니 또 꺼림직하고 말이죠. 이때 우리를 만족시킬 수 있는게 휘발성으로 사용할 수 있는 Cached와 Session입니다. Spring에서도 해당 기능을 쉽게 구현 할 수 있도록 제공해주고 있는데요. 요즘은 이런 기능을 Redis를 이용하여 많이 쓴다고 합니다. 그런데 Spring은 별도의 벤더를 지정하지 않아도 기본적으로 내장되어있는 Session과 Cache가 있습니다. 오늘은 이것들에 대해서 알아보는 시간을 가져보겠습니다.

 


 

Cache

  • cache란? : 속도가 상대적으로 느린 시스템, 부하에 민감한 시스템의 앞에 가벼운 시스템을 두고 여러 전략[버퍼링, 대신 처리]을 이용하여 뒷단의 시스템의 부하를 줄이고 속도또한 높이는 방법

  • 대표적으로 사용되는 곳

    • 대표적인 cache의 사용처는 뜬금 없지만 CPU와 HDD/SDD(이하 하드디스크)입니다. CPU의 레지스터는 우리가 사용하는 하드디스크보다 훨씬 빠릅니다. 그래서 이 사이에 cache를 두어 CPU가 빠르게 처리할 수 있도록 하는것이지요.
    • 사실 우리가 DBMS를 사용하여 data를 저장할 때, 이 저장한 데이터는 어디에 저장될까요? 결국 하드디스크에 저장이됩니다. 그러면 DB에 쓰거나 읽거나 하는 행위는 CPU와 하드디스크의 교류가 있다는 것을 알 수 있습니다.
    • 하드디스크는 상대적으로 CPU에 비해 많이 느립니다. 그렇기 때문에 많은 처리가 들어오면 CPU는 다 처리했지만 하드디스크의 처리를 기다리는 Wait I/O가 길어질것입니다.
    • 이런 경우에 cache를 사용하여 데이터를 하드디스크가 아닌 조금 더 빠른 memory에 저장을 하는 전략을 취합니다. 이렇게 하면 CPU가 기다리는 시간과 부하가 감소하게 됩니다.

 

Spring에서 Cache 사용과 기본값

@EnableCaching // cache를 사용하겠다는 Annotaion!
@SpringBootApplication
public class WebmvcApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebmvcApplication.class, args);
    }

}

Spring Boot에서는 @EnableCacing 어노테이션을 통해 전체시스템에 cache[SPring Cache]가 활성화 되어있다는 것을 알릴 수 있습니다.

실제사용을 한다면 다음 과 같이 사용할 수 있습니다.

@Component
public class MathService {

    @Cacheable("piDecimals")
    public int computePiDecimal(int i) {
        // ...
    }

}

위의 예제에서 computePiDecial method가 많은 CPU자원을 소모한다고 하겠습니다. 위의 @Cacheable을 선언하면 해당 method를 호출했을때, 먼저 piDecimals라는 entry에 i와 매칭이 되는지 찾아봅니다. 만약 매칭되는 값을 찾아내면 computeDecimal method를 호출하지 않고 즉시 호출한 사람에게 반환합니다.

 

Spring은 cache Provider로 아래와 같은 지원을합니다.

  1. Generic
  2. JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
  3. EhCache 2.x
  4. Hazelcast
  5. Infinispan
  6. Couchbase
  7. Redis
  8. Caffeine

그런데 사실 위의 dependency를 주지 않고도 caching이 정상적으로 동작합니다. 그건 Spring Boot에서 기본적으로 cache를 지원하기 때문입니다.

 

별도의 CacheProvider를 사용하지 않으면 ConcurrentHashMap을 이용하여 Cache를 구현합니다.

 

자세한 내용은 아래 링크를 보시면 확인하실수 있습니다.

 

https://docs.spring.io/spring-boot/docs/2.1.8.RELEASE/reference/html/boot-features-caching.html#boot-features-caching-provider-simple

 

33. Caching

The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache and org.springframework.cache.CacheManager interfaces. If you have not defined a bean of type CacheManager or a CacheResolv

docs.spring.io


Session

  • Session이란? : http는 stateless입니다. 즉, 한번 통신에 대해서 요청에 대한 응답을 받으면 그 상태를 유지 하지 않는다는 특성을 가지고 있따라는 뜻입니다. 이런 특정으로 인해 화면의 이동에 대한 값 유지가 필요할 경우가 있는데 가능하지 않습니다. 이걸 가능하게 해주는 것이 Session과 Cookie입니다. 간단히 Session은 서버사이드에 정보를 저장하고 있는 것이며, Cookie는 클라이언트 사이드에 값을 저장하고 있는 것이다. 정확하진 않지만 간단히 말하면 이렇게 이해하시면 될것 같습니다.

  • 대표적으로 사용되는 곳

    • Session이 가장 많이 사용되는 곳으로는 Login기능과 멀티폼서브밋 정도가있습니다. 우리가 자기소개서를 씁니다. 1페이지에는 기본정보, 2페이지에서는 자기소개서를 낸다고 하겠습니다.
    • 1페이지의 기본정보를 완성하고 2페이지로 넘어갔습니다. 아때 화면이동과 동시에 Session에 1페이지의 정보를 저장해둡니다.
    • 2페이지에서 자기소개서를 씁니다. 자기소개서를 쓰다가 깜박 적지못한 기본정보가 있어서 앞페이지로 돌아갑니다.
    • 다시 돌아온 1페이지에서는 기존에 입력했던 정보를 보여줘야합니다. 만약 기본정보를 Session에 저장을 해 두었다면 그 정보를 바로 가져와서 뿌려줄 수 있을것 입니다.
  • 물론 임시저장과 같은 기능이 된다면 DB로 돌아갈 것입니다.

Spring에서 Session

@Controller
@SessionAttributes("orderSessionDTO")
public class OrderController {

    @GetMapping("/orders")
    public String toOrder(Model model) {
        model.addAttribute("orderSessionDTO", "order-page");
        return "orders";
    }
}

위의 예제는 멀티폼서브밋예제 입니다. Spring MVC 모델을 구현하고 있습니다.

 

@SessionAttributes("orderSessionDTO")라는 것은 "orderSessionDTO"라는 Model은 sessionStorage에 저장되어진다는 것을 명시했습니다. 이렇게 구현 후 우리가 "/orders" 이렇게 호출을 한다면 orderSessionDTO라는 sessionID에는 order-page라는 값이 들어갈것입니다.

 

Session또한 Spring에서 지원을 해줍니다.

  1. JDBC
  2. Redis
  3. Hazelcast
  4. MongoDB

이렇게 말이지요. 하지만 Cache처럼 Spring에서 지원해주는 기본 SessionStorage는 없습니다.

 

그런데 사실 우리가 Session을 저장해보면 잘 되는것 같습니다. 이건 어떻게 된일일까요? 저도 찾지 못하여 결국 질문을 남겼습니다.

 

https://stackoverflow.com/questions/57738669/what-is-the-default-session-storage-for-spring-boot

 

What is the default Session Storage for Spring Boot?

I have read the Spring Boot documentation and I got knowledge about Spring Session from this document. But I see that HttpSession class works without adding any dependencies in my code. JDBC Redis

stackoverflow.com

 

친절하신 분들이 많네요 ^^. 답변을 보자면 바로 Spring Boot의 was의 기본값이 톰켓입니다. 이 톰켓에서 제공을 해준답니다. 체크된 답변을 읽어봐주시면 되며 설명드리자면 톰캣에서는 "SESSIONS.ser" 파일에 session의 상태가 저장된다고 합니다.


마무리

이렇게해서 Spring에서의 Cache와 Session에 대해서 알아보았습니다.

 

Spring-Boot Documentation을 읽다가 공유하고 싶은 부분이어서 공유해보았습니다. 다음번에 또 새로운 주제로 찾아오겠습니다.

 

감사합니다.

참조

https://en.wikipedia.org/wiki/Cache_(computing)#The_difference_between_buffer_and_cache

 

Cache (computing) - Wikipedia

Diagram of a CPU memory cache operation In computing, a cache ( (listen) kash,[1] or kaysh in AuE[2]) is a hardware or software component that stores data so that future requests for that data can be served faster; the data stored in a cache might be the r

en.wikipedia.org

https://docs.spring.io/spring-boot/docs/2.1.8.RELEASE/reference/html/boot-features-caching.html

 

33. Caching

The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache and org.springframework.cache.CacheManager interfaces. If you have not defined a bean of type CacheManager or a CacheResolv

docs.spring.io

https://tomcat.apache.org/tomcat-9.0-doc/config/manager.html#Standard_Implementation

 

Apache Tomcat 9 Configuration Reference (9.0.24) - The Manager Component

As documented above, every web application by default has standard manager implementation configured, and it performs session persistence across restarts. To disable this persistence feature, create a Context configuration file for your web application and

tomcat.apache.org