N대의 WAS에서 성능을 위한 Local cache와 Memory효율을 위한 Server Cache 를 사용중이다.

Spring에서 동시에 사용해보자.

Local Cache 는 Clustring 하지않은 Ehcache,
Server Cache 는 Infinispan Server HotRoad 방식을 사용한다.




[context-cache.xml]


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    					http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    					http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
    					http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

	<cache:annotation-driven />
	
	<!-- EHCache Local 형 -->
	<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager">
            <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
                <property name="configLocation" value="classpath:config/cache/ehcache.xml"></property>
            </bean>
        </property>
    </bean>
    
    <!-- Infinispan Server 형 -->
    <util:properties id="hotrod_data" location="classpath:properties/hotrod_data.properties" />
	<bean id="ispnCacheManager" class="org.infinispan.spring.provider.SpringRemoteCacheManagerFactoryBean">
		<property name="configurationProperties" ref="hotrod_data" />
	</bean>

	<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
		<property name="cacheManagers">
			<list>
				<ref bean="ehCacheManager" />
				<ref bean="ispnCacheManager" />
			</list>
		</property>
	</bean>
</beans>

[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">
    <diskStore path="java.io.tmpdir" />

    <defaultCache
        maxElementsInMemory="50000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="false"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    </defaultCache>

    <cache name="EHCACHE_MENU"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="0"
        timeToLiveSeconds="600"
        overflowToDisk="false"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    </cache>
</ehcache>

[Service.java]

@Cacheable("ISPN_EVENT")
public Map getEvent(String eventKey) {
	return query...
}
@Cacheable("EHCACHE_MENU")
public Map getMenu(String menuKey) {
	return query...
}

Redis 를 활용해서 Cache를 적용해보자..


우선 Redis Client는 http://www.redis.io/clients 에서 확인되는바와 같이 종류가 여러가지다.

그런데 Spring Data Redis 를 사용하면 별도의 Client가 필요 없네...(Interface만 있고 구현체는 가져다 쓰는줄 알았더니 아니네요.)


Source Code에서 사용법과 Method Annotataion 사용법을 보자.


[build.gradle]

dependencies {
	compile springDependencies // Spring 3.2.x
	compile 'org.springframework.data:spring-data-redis:1.3.4.RELEASE'
}


[context-cache.xml]



 
	
 
	
		
		
		
	
 
	
		
		
		
	
 
	
		
	
	
	
	
		
	
 
	
		
		
	    
	    
	    
		    
				
				
			
		
		
		
			
	            BANNER
	            EVENT
	        
		
	
 
	
	    
	    
	
 
	
	    
	    
	
 


[RedisTestCase.java]

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
		"classpath*:config/spring/context-common.xml",
		"classpath*:config/spring/context-cache.xml",
		"classpath*:config/spring/context-datasource.xml"
})
public class RedisTestCase {
    @Resource Cache cacheEvent;
    @Resource Cache cacheBanner;
 
    @Resource AuthService authService; 
 
    @Test
    public void test() {
    	User user = new User();
		user.setUserNm("ddakker");
	 
		cacheEvent.put("a", "zzz");
		String a = cacheEvent.get("a");
		System.out.println("a: " + a);
	 
		cacheBanner.put("user", user);
		User resultUser = cacheBanner.get("user");
		System.out.println("user: " + resultUser);
    }
 
}
 
@Test
public void testAnnotation() {
    // DB 쿼리 호출
    List authList = authService.getList();
    System.out.println("authList: " + authList);
 
    // DB 쿼리 호출 않음
    authList = authService.getList();
    System.out.println("authList: " + authList);
 
    Auth auth = new Auth();
    auth.setSearchKey("AUTH_CD");
    auth.setSearchKwd("ROLE_USER");
 
    // DB 쿼리 호출
    authList = authService.getList(auth);
    System.out.println("authList user: " + authList);
 
    // DB 쿼리 호출 않음
    authList = authService.getList(auth);
    System.out.println("authList user: " + authList);
}


[AuthService.java]

// @Cacheable 의 key나 조건의 디테일한 제어에 대한 설멍은 - http://dev.anyframejava.org/docs/anyframe/plugin/optional/cache/1.0.3/reference/html/ch01.html
@Service
public class AuthService {
	@javax.annotation.Resource AuthMapper authMapper;
 
	@Cacheable(value="BANNER")
	public List getList() {
		return authMapper.getList(new Auth());
	}
 
	@Cacheable(value="EVENT")
	public List getList(Auth authVo) {
		return authMapper.getList(authVo);
	}
}

oscache-2.3.2.jar 가 기존에 포함되어 있길래 재대로 활용해보았다.


하지만 운영서버에서 서버가 버벅되다 죽는것이 확인되었다.


이유를 못 찾는 와중에 WAS 시스템 엔지니어로 부터 OSCache문제라는 통보를 받았다 ㅠ


구글링도 해보았지만 해결책을 쉽게 찾지 못 하였다.


캐쉬 최대 갯수도 늘려보아도 소용이 없던 찰라에 oscache 버전을 최신으로 교체해보았다.


결론은.. 원활하게 운영중이다..


이런. ㅠㅠ


현재 oscache-2.4.1.jar 버전으로 정상 가동중이다.


+ Recent posts