์ž๋ฐ”์—์„œ ์ดˆ๊ฐ„๋‹จ ์บ์‹œ ์‚ฌ์šฉํ•˜๊ธฐ

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์˜ค๋Š˜์€ ์บ์‹œ ๊ด€๋ จ ๋‚ด์šฉ์„ ๋“ค๊ณ  ์™”์Šต๋‹ˆ๋‹ค.

ํšŒ์‚ฌ์—์„œ ๊ด€๋ฆฌ์ค‘์ธ ๊ด€๋ฆฌ์ž ์›น์•ฑ์—์„œ ํŠน์ • ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๋ฒ„ํŠผ์„ ๊ด‘ํด๋ฆญ ํ•˜์‹œ๋Š” ์ „์ง ํ”„๋กœ๊ฒŒ์ด๋จธ ๊ฐ™์€ ๋ถ„์ด ๊ณ„์…”์„œ ์ž๊พธ ์—๋Ÿฌ๊ฐ€ ๋‚˜๊ธธ๋ž˜ ๊ฐœ์„  ๋ฐฉ์•ˆ์„ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ ํ•œ ๋ฒˆ ํด๋ฆญํ•ด์„œ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰์ด ๋˜์—ˆ๋‹ค๋ฉด 1๋ถ„ ๋™์•ˆ ์žฌ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๋„๋ก ์บ์‹œ๋ฅผ ์ด์šฉํ•ด๋ณด๋ฉด ์ข‹๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํŠน์ • API๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์บ์‹œ์— ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด๋†“๊ณ  1๋ถ„ ๋‚ด์— ๋™์ผํ•œ ๋‚ด์šฉ์œผ๋กœ API ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๊ฒฝ์šฐ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•˜๋ฉด ๋˜๊ฒ ๋‹ค ์‹ถ์—ˆ์ฃ . ๊ทธ๋ฆฌ๊ณ  ์˜ˆ์ „์— ์นด์นด์˜คํ†ก๊ณผ ์—ฐ๋™ํ•˜์—ฌ G์‚ฌ์˜ ๋งค๋‹ˆ์ €๋“ค์ด ์‚ฌ์šฉํ•˜๋Š” ์ฑ—๋ด‡์„ ๋งŒ๋“  ์ ์ด ์žˆ๋Š”๋ฐ ์ด ๋•Œ Ehcache ๋ฅผ ์‚ฌ์šฉํ•ด๋ณธ์ ์ด ์žˆ์–ด์„œ ์ด๋ฒˆ์—๋„ ๋™์ผํ•˜๊ฒŒ Ehcache๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ฒ ๋‹ค ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

์šฐ์„  ํ˜„์žฌ ์ŠคํŽ™์€ ๋ฐฑ์—”๋“œ SpringFramework 4 ๊ธฐ๋ฐ˜์ด๊ณ  ํ”„๋ก ํŠธ์—”๋“œ๋Š” ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ์ด์šฉํ•œ ๊ตฌ์‹ ์•ฑ์ž…๋‹ˆ๋‹ค. (์Šคํ”„๋ง ๋ถ€ํŠธ๋กœ ์ „ํ™˜ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ๋” ์ค‘์š”ํ•œ ์—…๋ฌด๋“ค์ด ๋งŽ์•„ ์ƒ๊ฐ๋งŒ ํ•˜๊ณ  ์žˆ๋‹ค๋Š”...ใ…œใ…œ) AWS์˜ Tomcat 8 ํ”Œ๋žซํผ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋น„์Šค ์ค‘์ด์ฃ .

 

Ehcache ์— ๋Œ€ํ•ด์„œ ์˜ค๋žœ๋งŒ์— ๊ตฌ๊ธ€๋ง์„ ํ•ด๋ณด๋‹ˆ Jcache๋ฅผ ์ง€์›ํ•œ๋‹ค๊ณ  ํ•˜์—ฌ ํ‘œ์ค€์ธ Jcache๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. Jcache๋Š” JSR-107 ํ‘œ์ค€์„ ๋”ฐ๋ฅด๋Š” ์ž๋ฐ”์—์„œ ์ œ๊ณตํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ์ด ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š” ๊ตฌํ˜„์ฒด๋“ค์—๋Š” Ehcache ๋ฟ ์•„๋‹ˆ๋ผ Hazelcast, Oracle Coherence, Infinispan ๋“ฑ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ž๋ฐ”์—์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์บ์‹ฑํ•˜๊ธฐ (Ehcache๋ฅผ ์ด์šฉํ•œ Jcache ์‚ฌ์šฉ๋ฒ•)

์šฐ์„  pom.xml ํŒŒ์ผ์— ์•„๋ž˜ ๋‘ ๊ฐœ์˜ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>3.9.0</version>
        </dependency>

        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>1.1.1</version>
        </dependency>

ehcache, jcache ๋ชจ๋‘ ํฌ์ŠคํŒ… ์‹œ์  ์ตœ์‹ ๋ฒ„์ „์œผ๋กœ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  CacheConfig ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.cache.spi.CachingProvider;


@Configuration
public class CacheConfig {

    @Bean
    public Cache<String, String> syncCache() {

        CachingProvider provider = Caching.getCachingProvider();
        CacheManager cacheManager = provider.getCacheManager();
        MutableConfiguration<String, String> configuration =
                new MutableConfiguration<String, String>()
                        .setTypes(String.class, String.class)
                        .setStoreByValue(false)
                        .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.ONE_MINUTE));
        return cacheManager.createCache("syncCache", configuration);
    }
}

์ด ์„ค์ • ๋ถ€๋ถ„์ด ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ผํ…๋ฐ์š”, ํŠนํžˆ ์บ์‹œ๋งŒ๋ฃŒ์ •์ฑ…(expiry policy) ์„ค์ •ํ•˜๋Š” ๋ถ€๋ถ„์€ ์ž˜ ํ™•์ธํ•˜์‹œ๋Š” ๊ฒƒ์„ ๊ถŒ์žฅ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

jcache์—์„œ ์ œ๊ณตํ•˜๋Š” ๋งŒ๋ฃŒ์ •์ฑ…์€ 5๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

- AccessExpiryPolicy

- CreatedExpiryPolicy

- EternalExpiryPolicy

- ModifiedExpiryPolicy

- TouchedExpiryPolicy

 

๊ฐ๊ฐ ํŠน์ • ๋งŒ๋ฃŒ์ •์ฑ…์„ ์œ„ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ๋“ค์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด EternalExpiryPolicy๋Š” ์บ์‹ฑ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŒ๋ฃŒ๋˜์ง€ ์•Š๋Š” ๋ฌด๊ธฐํ•œ ์ €์žฅํ•˜๋Š” ์ •์ฑ…์ด์ฃ . ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ตฌ๊ธ€๋ง ํ•ด๋ณด์‹œ๋ฉด ๋งŽ์€ ์ž๋ฃŒ๋“ค์ด ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ๋Š” CreatedExpiryPolicy๋ฅผ ์‚ฌ์šฉํ•ด์„œ Duration์œผ๋กœ 1๋ถ„์„ ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋ ๋งŒํ•œ ์‹œ๊ฐ„๋“ค์ด staticํ•˜๊ฒŒ ์ •์˜๋˜์–ด ์žˆ์œผ๋‚˜ ์ •์˜๋˜์–ด์žˆ์ง€ ์•Š์€ ๋‹ค๋ฅธ ์‹œ๊ฐ„์„ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•  ๊ฒฝ์šฐ new Duration(TimeUnit timeUnit, long durationAmount) ์„ ์ด์šฉํ•˜์—ฌ ์ปค์Šคํ…€ํ•˜๊ฒŒ ์ •์˜ํ•ด์ค„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด์ œ ์ € ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•  CacheService๋ผ๋Š” ์„œ๋น„์Šค ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค.

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.cache.Cache;

@Service
@RequiredArgsConstructor
public class CacheService {

    private final Cache<String, String> syncCache;

    public boolean isCached(String key) {
        return syncCache.containsKey(key);
    }

    public void doCache(String key, String value) {
        syncCache.put(key, value);
    }

    public boolean remove(String key) {
        return syncCache.remove(key);
    }

}

 

์ด์ œ ํ•ด๋‹น ์„œ๋น„์Šค๋ฅผ ๊ฐ€์ ธ๋‹ค ์“ฐ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๊ผผ๊ผผํ•˜์‹  ๋ถ„๋“ค์€ ์ข€ ์ด์ƒํ•œ๊ฒŒ ๋ˆˆ์— ๋Œ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. 

ehcache ํŒจํ‚ค์ง€์—์„œ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•œ ๋ถ€๋ถ„์ด ํ•˜๋‚˜๋„ ์—†๋‹ค๋Š” ๊ฒƒ์ด์ฃ .

๊ทธ๋Ÿผ pom.xml ํŒŒ์ผ์—์„œ ehcache ์˜์กด์„ฑ์„ ์ œ๊ฑฐ ํ•ด๋ณผ๊นŒ์š”??

๊ทธ๋Ÿผ ์•„๋ž˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.cache.Cache]: Factory method 'syncCache' threw exception; nested exception is javax.cache.CacheException: No CachingProviders have been configured
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
	... 67 more
Caused by: javax.cache.CacheException: No CachingProviders have been configured
	at javax.cache.Caching$CachingProviderRegistry.getCachingProvider(Caching.java:391)
	at javax.cache.Caching$CachingProviderRegistry.getCachingProvider(Caching.java:361)
	at javax.cache.Caching.getCachingProvider(Caching.java:151)

 

์ฆ‰, ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๋Š” API๋Š” javax.cache ํŒจํ‚ค์ง€ ๋‚ด์— ์ •์˜๋˜์–ด์žˆ๋Š” ๊ฒƒ์ด์ง€๋งŒ ๋‚ด๋ถ€์ ์œผ๋กœ ehcache์—์„œ ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด๋กœ ์‹คํ–‰๋œ๋‹ค๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์–ด๋–ค๊ฐ€์š”? ์ •๋ง ์‰ฝ๊ฒŒ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜์ฃ ?

 

์ด์ƒ์œผ๋กœ ehcache๋ฅผ ํ™œ์šฉํ•œ jcache ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ํฌ์ŠคํŒ…์„ ๋งˆ์นฉ๋‹ˆ๋‹ค.

 

 

 

์ฐธ๊ณ ์ž๋ฃŒ

- www.ehcache.org/

- www.ehcache.org/documentation/3.3/107.html

- www.baeldung.com/jcache