์๋ฐ์์ ์ด๊ฐ๋จ ์บ์ ์ฌ์ฉํ๊ธฐ
์๋ ํ์ธ์, ์ค๋์ ์บ์ ๊ด๋ จ ๋ด์ฉ์ ๋ค๊ณ ์์ต๋๋ค.
ํ์ฌ์์ ๊ด๋ฆฌ์ค์ธ ๊ด๋ฆฌ์ ์น์ฑ์์ ํน์ ๊ธฐ๋ฅ์ ํ๋ ๋ฒํผ์ ๊ดํด๋ฆญ ํ์๋ ์ ์ง ํ๋ก๊ฒ์ด๋จธ ๊ฐ์ ๋ถ์ด ๊ณ์ ์ ์๊พธ ์๋ฌ๊ฐ ๋๊ธธ๋ ๊ฐ์ ๋ฐฉ์์ ๊ณ ๋ฏผํ๋ค๊ฐ ํ ๋ฒ ํด๋ฆญํด์ ์ ์์ ์ผ๋ก ์คํ์ด ๋์๋ค๋ฉด 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 ์ฌ์ฉ๋ฒ์ ๋ํ ํฌ์คํ ์ ๋ง์นฉ๋๋ค.
์ฐธ๊ณ ์๋ฃ
'๐ป Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
AWS Elasticsearch ISM์ ํ์ฉํ ์ธ๋ฑ์ค ์๋์ญ์ (0) | 2021.04.21 |
---|---|
SpringBoot 2 http response utf-8 ์ค์ ํ๊ธฐ (0) | 2021.03.11 |
์คํ๋ง ์ํ์ฐธ์กฐ ๋ฌธ์ ํด๊ฒฐํ๊ธฐ (How to avoid circular reference) (0) | 2020.12.11 |
์คํ๋ง ์์กด์ฑ ์ฃผ์ (DI) (0) | 2020.12.10 |
[์๋ฃ๊ตฌ์กฐ] AVL ํธ๋ฆฌ ํ์ ํ๊ธฐ (rotation of AVL tree) (1) | 2020.12.04 |