Spring Cache: CaffeineCache 설정

2024. 11. 6. 12:32JAVA/Spring

CaffeineCache는 무엇인가?

CaffeineCache는 Java 기반의 고성능 캐시 라이브러리인 Caffeine을 사용하여 데이터를 메모리에 캐시하는 기능입니다.

 

Spring Boot CaffeineCache 설정

의존성 라이브러리 추가

implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'com.github.ben-manes.caffeine:caffeine'

 

Cache 설정 클래스 추가

다음과 같이 설정 클래스를 구현하여 CaffeineCacheManager 스프링 빈을 정의합니다. 저 같은 경우 weatherCache 캐시를 10분으로 설정하기 위해서 다음과 같이 인스턴스 생성시 "weatherCache"를 전달합니다. 그리고 Mono, Flux와 같은 Reactive Type을 캐싱하기 위해서는 CaffineCacheManager 인스턴스의 setAsyncCacheMode 메서드에 true를 전달하여 비동기 캐시 모드를 활성화해야합니다.

@Configuration
@EnableCaching
public class CacheConfig {
	@Bean
	public CaffeineCacheManager cacheManager() {
		CaffeineCacheManager cacheManager = new CaffeineCacheManager("weatherCache");
		cacheManager.setCaffeine(caffeineCacheBuilder());
		cacheManager.setAsyncCacheMode(true);
		return cacheManager;
	}

	@Bean
	public Caffeine<Object, Object> caffeineCacheBuilder() {
		return Caffeine.newBuilder()
			.expireAfterWrite(10, TimeUnit.MINUTES)
			.maximumSize(100);
	}
}
  • 기본적으로 캐시 TTL은 10분으로 설정
  • 최대 캐시 항목은 100개로 설정

 

@Cacheable 애노테이션 추가하여 캐시하기

특정 메서드의 결과를 캐시하기 위해서는 메서드 레벨에 @Cacheable 애노테이션을 추가해야 합니다. 예를 들어 다음 코드의 fetchWeatherByCity 메서드를 보면 Mono<WeatherResponse> 타입을 캐싱하기 위해서 다음과 같이 @Cacheable 애노테이션을 추가합니다.

@Slf4j
public class WeatherWebClient {
	private final WebClient webClient;
	private final String appid;

	public WeatherWebClient(WebClient webClient, String appid) {
		this.webClient = webClient;
		this.appid = appid;
	}

	@Cacheable(value = "weatherCache", key = "#city")
	public Mono<WeatherResponse> fetchWeatherByCity(String city) {
		log.info("call fetchWeatherByCity, city={}", city);
		return webClient.get()
			.uri(uriBuilder -> uriBuilder
				.path("/data/2.5/weather")
				.queryParam("q", city)
				.queryParam("appid", appid)
				.queryParam("units", Units.METRIC)
				.build())
			.retrieve()
			.bodyToMono(WeatherResponse.class)
			.log();
	}
}

 

캐시 결과 확인하기

메서드의 결과가 캐시되었는지 확인하기 위해서 캐시 TTL 설정을 일시적으로 1분으로 설정한 후 실행하였습니다. 애플리케이션을 실행하면 내부적으로 스케줄링 메서드가 5초에 한번씩 fetchWeatherByCity 메서드를 호출하고 있는 상태입니다. 실행 결과를 보면 다음과 같습니다.

로그 결과를 확인해보면 처음 메서드 호출시 "call fetchWeatherByCity, city=Seoul" 로그가 찍힌 것을 확인할 수 있고 그 밑에 1분후에 다시 동일한 로그가 찍힌 것을 볼수 있습니다.  위 실행 결과를 통해서 캐시가 정상적으로 1분으로 적용되었습니다.

 

References

https://medium.com/naverfinancial/%EB%8B%88%EB%93%A4%EC%9D%B4-caffeine-%EB%A7%9B%EC%9D%84-%EC%95%8C%EC%95%84-f02f868a6192