앞선 포스팅에서 EHCache 사용을 위한 셋팅에 대해 작성하였습니다.
이번 포스팅은 실제 캐시를 활용하여 코드를 작성해보겠습니다.
예제는 클라이언트로부터 요청이 발생하면 아주 간단한 값을 반환하는 API를 작성해보도록 하겠습니다.
@RestController
@RequiredArgsConstructor
public class CacheController {
private final CacheService cacheService;
@GetMapping("/cache/test")
public ResponseEntity<String> getCacheData(CacheDto cacheDto){
return new ResponseEntity<>(cacheService.isUsingCacheInfo(cacheDto.getId()), HttpStatus.OK);
}
@Getter @Setter
class CacheDto{
private Integer id;
}
}
@Entity
@Getter
public class Cache {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer cacheId;
private String using;
}
@Service
@RequiredArgsConstructor
public class CacheService {
private final CacheRepository cacheRepository;
@Cacheable(value = "cacheInfo", key="#id")
@Transactional(readOnly = true)
public String isUsingCacheInfo(Integer id){
Cache cacheInfo = cacheRepository.findByCacheId(id);
if(cacheInfo.getUsing().equals("yes")){
return "Yes";
}
return "No";
}
}
public interface CacheRepository extends JpaRepository<Cache, Integer> {
Cache findByCacheId(Integer cacheId);
}
위 예제에서 자세히 봐야할 부분은 CacheService의 isUsingCacheInfo 메소드입니다.
isUsingCacheInfo 메소드에 동일한 파라미터(키) 값을 가진 호출이 발생한다면 데이터베이스에 접근하지 않고 EHCache의 지정한 저장소(heap, off-heap, Disk)에서 캐시 데이터를 읽은 뒤 반환하게 됩니다.
만약, 캐시 저장소를 heap 영역으로 지정하였다면 캐시 처리한 데이터의 참조가 어느정도 발생하는지 확인하여 캐시 데이터를 얼마나 유지시킬지 등을 한번 고민해보시는 것을 추천드립니다.
자주 참조되지 않는 데이터를 힙 영역에 지속적으로 유지시키다보면 아무래도 가비지 컬렉터 대상이되므로 GC 횟수가 오히려 증가하게 되는 불상사가 발생할 수 있기 때문입니다.
이번 프로젝트를 통해 EHCache를 사용하게 되면서 확실히 성능상의 효과를 보았으며 혹여나 동일 데이터 반복 조회를 하는 부분에 성능개선을 하고 싶으신 분들이 있으시다면 한번 쯤 사용해보시는 것도 괜찮을 것으로 생각됩니다.