egovFramework에서 Java 캐시 라이브러리 Ehcache 사용 방법

API 요청 결과를 Ehcache와 같은 캐시 시스템에 저장하고 재활용하면,
요청이 많이 몰리는 시간에 조회 속도가 느려지는 성능 이슈를 해결할 수 있습니다.


Ehcache 설정 방법

Ehcache 의존성 추가

<dependency>
  <groupId>net.sf.ehcache</groupId>
  <artifactId>ehcache-core</artifactId>
  <version>2.6.9</version>
  <exclusions>
    <exclusion>
      <artifactId>slf4j-api</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>net.sf.ehcache</groupId>
  <artifactId>ehcache</artifactId>
  <version>2.9.0</version>
</dependency>

Maven을 사용하는 경우, pom.xml 파일에 Ehcache 의존성을 추가합니다.

ehcache.xml 설정 파일 작성

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect"
  dynamicConfig="true">
	
  <diskStore path="java.io.tmpdir" />
	 
  <defaultCache 
    maxElementsInMemory="10000" 
    eternal="false" 
    timeToIdleSeconds="120" 
    timeToLiveSeconds="120" 
    overflowToDisk="true"
    diskSpoolBufferSizeMB="30" 
    maxElementsOnDisk="10000000" 
    diskPersistent="false" 
    diskExpiryThreadIntervalSeconds="120" 
    memoryStoreEvictionPolicy="LRU"
    statistics="false" />
	
	<cache name="캐시명1" 
    maxElementsInMemory="1000" 
    eternal="false" 
    timeToIdleSeconds="1800" 
    timeToLiveSeconds="1800" 
    overflowToDisk="true" 
    diskPersistent="false"
    maxElementsOnDisk="100000" 
    memoryStoreEvictionPolicy="LRU" />
			
	<cache name="캐시명2" 
    maxElementsInMemory="1000" 
    eternal="false" 
    timeToIdleSeconds="1800" 
    timeToLiveSeconds="1800" 
    overflowToDisk="true" 
    diskPersistent="false"
    maxElementsOnDisk="100000" 
    memoryStoreEvictionPolicy="LRU" />

</ehcache>

캐시 구분에 따라 캐시 옵션을 다르게 설정할 수 있습니다.

Ehcache 캐시 옵션

maxElementsInMemory 메모리 내에 보관될 최대 엔트리 수
eternal 캐시 항목이 만료되지 않고 영구적으로 보관되는지 여부
timeToIdleSeconds 캐시 항목이 최근에 액세스되지 않고 유효한 시간(초)
timeToLiveSeconds 캐시 항목이 캐시에 보관될 최대 시간(초)
overflowToDisk 메모리 내 최대 엔트리 수를 초과하는 경우 디스크에 저장 여부
diskPersistent 캐시가 종료 후 디스크에 캐시 항목 영구 저장 여부
maxElementsOnDisk 디스크에 보관될 최대 엔트리 수
memoryStoreEvictionPolicy 메모리 내 엔트리가 제거될 때 사용할 정책

context-cache.xml 설정 파일 작성

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
  
	<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
	    <property name="cacheManager">
	        <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
	            <property name="configLocation" value="classpath:egovframework/spring/com/ehcache.xml"/>
	        </bean>
	    </property>    
	</bean>
	
</beans>

egovFramework에서 Ehcache 캐시를 사용하도록 설정하는 XML입니다.

Spring XML 파일 로드 예시

package egovframework.com.cmm.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.XmlWebApplicationContext;

public class EgovWebApplicationInitializer implements WebApplicationInitializer {

	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		XmlWebApplicationContext rootContext = new XmlWebApplicationContext();
		rootContext.setConfigLocations(new String[] { "classpath*:egovframework/spring/com/**/context-*.xml" });
		rootContext.refresh();
		rootContext.start();
		
		servletContext.addListener(new ContextLoaderListener(rootContext));
	}
}

WebApplicationInitializer를 구현하여 애플리케이션 초기화 시 root 컨텍스트를 설정하고, ‘src/main/resources/egovframework/spring/com/context-cache.xml’ XML 설정 파일을 로드합니다.


Ehcache 사용 방법

Ehcache 사용 예시

// 이름이 ehcache인 캐시 bean 주입 받기
@Resource(name = "ehcache")
	Ehcache ehCache;

public static List<Items> 유사문항조회함수(String 문항ID, String 과목CD) throws Exception {
		
		String ehCacheName = "캐시명1";
		Ehcache cache = ehCache.getCacheManager().getCache(ehCacheName);
		Element value = null;
		
		// 캐시명_문항ID_과목CD로 이루어진 캐시Key 생성
		String cacheKey = ehCacheName + "_" + 문항ID + "_" + 과목CD ;

		if (cache == null) {
			// 캐시 객체가 없는 경우, API 조회
			return 유사문항조회API호출함수(문항ID, 과목CD);

		} else {
			// 캐시 객체가 있는 경우
			value = cache.get(cacheKey);
			List<Items> result = null;

			if (value == null) {
				// 캐시에 저장된 값이 없으면, API 조회 후 캐시에 키-값 저장하고 값 반환
				result = 유사문항조회API호출함수(문항ID, 과목CD);
				cache.put(new Element(cacheKey, result));

			}else {
				// 캐시에 저장된 값이 있으면, 저장된 값 반환
				result = (List<Items>) value.getObjectValue();
			}

			return result;
		}
	}

문항ID와 과목CD로 유사문항 API 조회 시 조회 결과를 캐시에 저장하고,
최근 1800초(30분) 내에 동일한 조회 요청 시 저장된 결과를 리턴하는 코드입니다.

Leave a comment