Hello World

spring cache의 적용(ehcache) 본문

Spring/3.x

spring cache의 적용(ehcache)

EnterKey 2016. 4. 18. 11:33
반응형

처리 속도 개선을 위해 cache를 적용했다.

시스템간 연동으로 접속부하, 네트웍부하가 동시에 생겨 속도저하가 심각한 화면이 생김!!

문제는 조회조건부 - 회계년도, 부서, 코드관련..... 
가져오는 데이터는 거의 동일한데도...
화면이 바뀌거나, 조회콤보 선택처리에 DB까지 데이터 엑세스가 반복적으로 발생.

이 부분에 cache를 적용해볼 생각으로 자료를 찾았더니 가장 많이 선택된 솔루션이 ehcache.....
ehcache를 심도있게 학습하고 적용할 상황은 아니라서 
spring에 annotation기반으로 빠르게 적용할 수 있는 방법을 찾음 ehcache-spring-annotations

현재 개발중인 시스템에 적용된 spring버전은 3.0.5.RELEASE이다.
maven을 사용하고 있다면 다음과 같은 dependency추가가 필요하다.

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</artifactId>
   <version>3.0.5.RELEASE</version>
</dependency>

<dependency>
   <groupId>com.googlecode.ehcache-spring-annotations</groupId>
   <artifactId>ehcache-spring-annotations</artifactId>
   <version>1.1.3</version>
</dependency> 

위 2개의 dependency를 추가하면 그와 연결된 관련 dependency까지 setting이 완료된다. 
maven의 혜택...ㅋ~~~~ 

maven에 의해 ehcache관련 필수 라이브러리가 classpath상에 위치하게 되었으므로
설정과 코드수정만 남았다.

먼저 beans.xml 또는 applicationContext.xml 등 spring configuration파일의 
네임스페이스 부분에 추가설정이 필요

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
                  http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">
 
짙게 표시된 부분이  추가한 내용이다.

그리고 동일 설정파일에 아래 코드를 추가한다.

  <!-- declare ehCache -->
  <ehcache:annotation-driven />
  
  <ehcache:config cache-manager="cacheManager">
    <ehcache:evict-expired-elements interval="60" />
  </ehcache:config>
    
  <!-- ehCache bean -->
  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
    <property name="configLocation"  value="/WEB-INF/ehcache.xml"/>
  </bean> 
 
이제 설정 작업은 끝났다.
WEB-INF/ root 디렉토리에 다음과 같은 내용의 ehcache.xml파일을 생성하자.

<?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">   
    
    <defaultCache 
     eternal="false" 
     maxElementsInMemory="1000"
        overflowToDisk="false" 
        diskPersistent="false" 
        timeToIdleSeconds="0"
        timeToLiveSeconds="600" 
        memoryStoreEvictionPolicy="LRU"/>

    <cache 
     name="budgetCache" 
     eternal="false"
        maxElementsInMemory="100" 
        overflowToDisk="false" 
        diskPersistent="false"
        timeToIdleSeconds="0" 
        timeToLiveSeconds="300"
        memoryStoreEvictionPolicy="LRU" />
        
    <cache 
     name="accountCache" 
     eternal="false"
        maxElementsInMemory="100" 
        overflowToDisk="false" 
        diskPersistent="false"
        timeToIdleSeconds="0" 
        timeToLiveSeconds="300"
        memoryStoreEvictionPolicy="LRU" />
        
</ehcache>

배포파일의 element, 설정값 등은
환경에 맞게 수정해서 사용하면 될 것이다.

지금까지 한 작업을 정리해보면...
1. dependency추가 완료
2. spring configuration 파일(beans.xml 또는 applicationContext.xml 등 설정 파일) 설정 추가 완료
3. ehcache configuration 파일 작성 및 배포준비 완료(WEB-INF)

이제 실제 Java code에 적용하는 일만 남았다...
다음 코드는 
@Cacheable annotation을 적용한 소스의 일부이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package pe.tuenas.prototype.soapservice.budget.impl;
 
import .... 생략
 
@WebService(
        endpointInterface="pe.tuenas.prototype.soapservice.budget.BudgetService",
        serviceName="budgetService")
public class BudgetServiceImpl implements BudgetService {
 
    @Cacheable(cacheName = "budgetCache")
    @Override
    public List<budgettype> getBudgetTypeList(String workDate) {
 
        return getBudgetTypeDao().findBudgetTypeByFYear(
                getFinancialYearDao().findFinancialYearByDate(workDate));
    }
     
    @Cacheable(cacheName = "budgetCache")
    @Override
    public List<budgettype> getBudgetTypeListByBusinessYear(String businessYear) {
        return getBudgetTypeDao().findBudgetTypeByFYear(
                getFinancialYearDao().findFinancialYearByBusinessYear(businessYear));
    }
     
    @Cacheable(cacheName = "budgetCache")
    @Override
    public List<businesscode> getBusinessCodeList(String workDate) {
 
        return getBusinessCodeDao().findBusinessCodeByDate(workDate);
    }
}
 
</businesscode></budgettype></budgettype>


@Cacheable annotation선언만으로 캐시기능은 훌륭하게 작동된다.
실제로 한게 너무 없어 황당할 정도...

서비스 영역의 캐시가 완료되면 client영역에서 최초 조회시 원래 속도로 나오고
반복적인 조회에서는 엄청난(?) 속도향상이 이뤄졌다.

cache적용이 유용한  부분은 
코드성 데이터 조회 부분, 
기본 데이터이지만 반복적으로 호출되는 부분  
출력물의 코드, 부서 매핑이 필요한 부분 등일 것이다..

웹상에 공개된 문서나 자료만을 참고해서 급하게 적용하느라 
심도있는 이해나 준비가 부족했다.
추후 보완이 필요한 부분이다.

출처: http://ironheel.tistory.com/44


반응형
Comments