본문 바로가기
Project/MangoPlate Clone

EhCache 설정

by 혀눅짱 2023. 2. 24.

모바일 기능중에 카테고리 목록을 가져와 필터로 뿌리는 기능이 있다. 이걸 사실 계속 db조회해도 토이프로젝트이다 보니 이슈가 발생하진 않지만 여러가지 설정 공부도 하고 구색도 맞춰볼겸 캐시를 적용해보기로했다.

통상적으로 뭐 메뉴나 카테고리는 크게 바뀔게없으니까 지속적으로 리스트 호출할 때마다 db조회는 좀 비효율적이다.

 

처음엔 걍 이니셜라이징빈을 implements해서 최초 서버 뜰때 스태틱 리스트 변수에 담아두고 스태틱으로 계속 쓸까도 해봤는데 현재 근무하고있는 실무프로젝트에서 메뉴리스트 호출시 사용하는 EhCache를 적용해보기로했다.

 

역시 Gradle 기반 프로젝트여서 설정도 간편한 편이다

 

Build.Gradle

//ehcache
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'net.sf.ehcache:ehcache:2.10.3'

일단 라이브러리 추가해준다. 

xml설정 파일이다 캐시 이름을 categoryList라고 명명했다.

해당 캐시 속성 목록이다.

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">


    <cache name="categoryList"
           maxEntriesLocalHeap="10000"
           maxEntriesLocalDisk="1000"
           eternal="false"
           diskSpoolBufferSizeMB="20"
           timeToIdleSeconds="300"
           timeToLiveSeconds="600"
           memoryStoreEvictionPolicy="LFU"
           transactionalMode="off">
    </cache>

</ehcache>​
property desc
maxEntriesLocalHeap 메모리에 생성될 객체의 최대 수(0: 제한없음)
maxEntriesLocalDisk 디스크(DiskStore)에 저장될 객체의 최대 수(0: 제한없음)
eternal 저장된 캐시를 제거할지 여부. 설정이 true 인 경우 저장된 캐시는 제거되지 않으며 timeToIdleSeconds, timeToLiveSeconds 설정은 무시
timeToIdleSeconds 생성후 해당 시간 동안 캐쉬가 사용되지 않으면 삭제, 0은 삭제되지 않음
timeToLiveSeconds 생성후 해당 시간이 지나면 캐쉬는 삭제. 0은 삭제되지 않음
diskSpoolBufferSizeMB 디스크 캐시에 쓰기 모드로 들어갈때, 사용될 비동기 모드의 스폴 버퍼 크기 설정.(OutOfMemory 에러가 발생 시 설정한 크기를 낮추는 것이 좋음)
memoryStoreEvictionPolicy maxEntriesLocalHeap 설정 값에 도달했을때 설정된 정책에 따라 객체가 제거되고 새로 추가(LRU : 사용이 가장 적었던 것부터 제거, FIFO : 먼저 입력된 것부터 제거, LFU : 사용량이 적은 것부터 제거)
persistence strategy diskStore 사용 설정("localTempSwap": Temp DiskStore 사용, "none": Only Memory 사용)

그리고 생성한 xml 파일을 캐시파일로 설정할거다라는 명시를 해줘된다.

 

application.properties

# cache ##
spring.cache.ehcache.config=classpath:cache/ehcache.xml

 

그리고 main메소드가있는 application 클래스에 캐시 어노테이션을 사용할거라는 명시를 해줘야된다

@EnableCaching

요녀석을 클래스 선언부에 추가해주자.

 

이제 캐시를 적용하고싶은 로직에 캐시만 적용해주면된다

public class CategoryService {

    private final CategoryRepository categoryRepository;

    @Cacheable("categoryList")
    public List<CategoryDto> getCategoryList(){
        return categoryRepository.findAll().stream().map(c -> new CategoryDto(c)).collect(Collectors.toList());
    }

}

@Cacheable 어노테이션에 xml에서설정한 캐시 name값을 적어주면된다.

 

그 후 테스트를 해본다

@RestController
@RequiredArgsConstructor
@Slf4j
public class CategoryController {

    private final CategoryService categoryService;

    @GetMapping("getCategoryList")
    public List<CategoryDto> getCategoryList(){
        long start = System.currentTimeMillis(); // 수행시간 측정
        List<CategoryDto> categoryList = categoryService.getCategoryList();
        long end = System.currentTimeMillis();
        log.info("카테고리 캐시 수행시간 : "+ (end - start)); // 수행시간 logging
        return categoryList;
    }
}

컨트롤러에서 캐시가적용된 서비스레이어 로직을 호출할때 수행시간을 로깅해보았다.

 

최초 호출시 콘솔

 

최초호출이라 db에 셀렉트 쿼리가 날라간다.

 

재차호출시 

쿼리도안날라가고 수행시간도 뭐 메소드호출도안하고 캐시에서꺼내니까 당연히 줄어든다

 

 

'Project > MangoPlate Clone' 카테고리의 다른 글

SpringSecurity 및 jwt 설정 1  (0) 2023.02.27
리뷰 및 메뉴 페이징 목록 구현  (1) 2023.02.27
JPA Auditing 설정  (0) 2023.02.24
간단한 logBack 설정  (0) 2023.02.20
메인 목록에 QueryDsl 필터링 추가  (0) 2023.02.17