모바일 기능중에 카테고리 목록을 가져와 필터로 뿌리는 기능이 있다. 이걸 사실 계속 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 |