Spring boot caffeine cache 설정 약술

39591 단어 ----FWSpringPL-Java
약술 하 다
프로젝트 는 Spring boot 개발 을 사용 하여 캐 시 기능 을 사용 하여 데이터베이스 압력 을 줄 여야 합 니 다.주로 사용 빈도 가 높 고 업데이트 빈도 가 낮은 설정 데 이 터 를 캐 시 하 는 데 사 용 됩 니 다.공식 적 으로 추천 하 는 실현 인 Caffine 을 선택 하 세 요.
도입 의존
<properties>
    <spring.boot.version>1.5.6.RELEASEspring.boot.version>
properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-dependenciesartifactId>
            <version>${spring.boot.version}version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-cacheartifactId>
dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeinegroupId>
    <artifactId>caffeineartifactId>
dependency>


기본 키 생 성기 설정
spring 이 제공 하 는 기본 값 은org.springframework.cache.interceptor.SimpleKeyGenerator이 며,사용 방법의 매개 변수 만 key 를 생 성 합 니 다.매개 변수 가 사용자 정의 조회 대상 이 라면 hashCode 와 equals()방법 을 다시 쓰 는 것 에 주의 하 십시오.
사용자 정의 KeyGenerator 설정
간단 한 KeyGenerator 를 구현 합 니 다.매개 변 수 는 사용자 정의 조회 대상 이 라면 toString()방법 을 다시 쓰 는 것 에 주의 하 십시오.
이루어지다
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.StringJoiner;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.interceptor.KeyGenerator;

public class CustomKeyGenerator implements KeyGenerator {

    private static final Logger logger = LoggerFactory.getLogger(CustomKeyGenerator.class);

    @Override
    public Object generate(Object target, Method method, Object... params) {

        String className = method.getDeclaringClass().getName();
        String methodName = method.getName();
        String paramHash = String.valueOf(Arrays.toString(params).hashCode());
        String cacheKey = new StringJoiner("_").add(className).add(methodName)
                .add(paramHash).toString();
        logger.debug("generate cache key : {}", cacheKey);

        return cacheKey;
    }
}

bean
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;

import cn.migu.pk.constant.CommonConstants;

@Configuration
public class CaffeineCacheConfig {

    private static final Logger logger = LoggerFactory.getLogger(CaffeineCacheConfig.class);

    @Bean(CacheConstants.CUSTOM_KEY_GENERATOR)
    public KeyGenerator createMapperKeyGenerator() {
        return new CustomKeyGenerator();
    }
}

기본 CacheManager 설정spring-boot-starter-cache가방 에 서 는 기본 적 인 CacheManager 를 제공 하여 CaffineCheManager 를 실현 합 니 다.모든 캐 시가 같은 설정 을 사용 하 는 것 이 단점 입 니 다.
properties 프로필
spring.cache.cache-names=cfgDataCache
spring.cache.caffeine.spec=maximumSize=500,refreshAfterWrite=120s,expireAfterWrite=600s

자바 설정 클래스

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.github.benmanes.caffeine.cache.CacheLoader;

@Configuration
public class CaffeineCacheConfig {

    private static final Logger logger = LoggerFactory.getLogger(CaffeineCacheConfig.class);

    @Bean
    public CacheLoader<Object, Object> createCacheLoader() {
        return new CacheLoader<Object, Object>() {
            @Override
            public Object load(Object key) throws Exception {
                logger.debug("cacheLoader load : {}", key);
                return null;
            }
        };
    }

    @Bean(CacheConstants.CUSTOM_KEY_GENERATOR)
    public KeyGenerator createMapperKeyGenerator() {
        return new CustomKeyGenerator();
    }
}
refreshAfterWrite정책 을 사 용 했 기 때문에com.github.benmanes.caffeine.cache.CacheLoaderbean 을 정의 해 야 합 니 다.CafeineCheManager 의 cacheLoader(CacheLoader)구성원 변 수 를 자동 으로 연결 합 니 다.
상수 류
public final class CacheConstants {

    /*
     *     
     */
    public static final String CFG_DATA_CACHE = "cfgDataCache";
    public static final String BIZ_DATA_CACHE = "bizDataCache";

    /*
     * KeyGenerator  
     */
    public static final String CUSTOM_KEY_GENERATOR = "customKeyGenerator";
}

사용자 정의 CacheManager 설정
Simple CacheManager 를 사용 하여 서로 다른 Cache 설정 을 사용 합 니 다.
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;

@Configuration
public class CacheManagerConfig {

    private static final Logger logger = LoggerFactory.getLogger(CacheManagerConfig.class);

    @Bean
    public CacheManager createCacheManager() {

        logger.info("cache manager initialize ...");

        LoadingCache<Object, Object> cfgDataCache = Caffeine.newBuilder()
                .maximumSize(100)
                .refreshAfterWrite(5, TimeUnit.MINUTES)
                .build(key -> load(key));

        LoadingCache<Object, Object> bizDataCache = Caffeine.newBuilder()
                .maximumSize(10_000)
                .expireAfterWrite(1, TimeUnit.HOURS)
                .build(key -> load(key));

        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(
                new CaffeineCache(CacheConstants.CFG_DATA_CACHE, cfgDataCache),
                new CaffeineCache(CacheConstants.BIZ_DATA_CACHE, bizDataCache)));
        return cacheManager;
    }

    @Bean(CacheConstants.CUSTOM_KEY_GENERATOR)
    public KeyGenerator createMapperKeyGenerator() {
        return new CustomKeyGenerator();
    }

    private Object load(Object key) throws Exception {
        logger.debug("cacheLoader load : {}", key);
        return null;
    }
}

회수 정책
이 사례 에서 주로maximumSize,refreshAfterWrite,expireAfterWrite세 가지 전략 을 설정 했다.이름 과 의 미 를 고려 하여maximumSize는 공간 을 바탕 으로 하 는 것 이 고refreshAfterWriteexpireAfterWrite은 시간 을 바탕 으로 하 는 것 이다.
  • refreshAfterWrite:캐 시 를 불 러 올 때 한 스 레 드 에서 캐 시 를 계산 하고 다른 스 레 드 는 오래된 값 을 직접 가 져 옵 니 다.
  • expireAfterWrite:캐 시 를 불 러 올 때 해당 스 레 드 를 막 고'자 물 쇠 를 가 져 오고 캐 시 를 계산 하 며 자 물 쇠 를 방출 합 니 다'

  • 이 예 에서 설정 한 데이터 의 캐 시 는refreshAfterWrite정책 을 사용 하기에 더욱 적합 합 니 다.
    주해 용법
    주해 예시
    spring boot 입구 류 에@EnableCaching주 해 를 추가 합 니 다.
    해당 방법 에서 해당 하 는 캐 시 주 해 를 사용 합 니 다.예 를 들 어 본 프로젝트 의 설정 데이터 캐 시 사용refreshAfterWrite정책 및@Cacheable주 해 를 사용 합 니 다.
    @Mapper
    public interface SysConstantMapper {
    
        @Cacheable(cacheNames = CacheConstants.CFG_DATA_CACHE,
                   keyGenerator = CacheConstants.CUSTOM_KEY_GENERATOR,
                   sync = true)
        List<SysConstantDO> selectRecordsByQO(@Param("cond") SysConstantQO cond);
    }
    

    사용자 정의 캐 시 주석
    주석 에 있 는 인자 가 많 고 복잡 해 보이면 캐 시 주 해 를 사용자 정의 할 수 있 습 니 다.예 를 들 어:
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.cache.annotation.Caching;
    
    @Caching(
        cacheable = {
            @Cacheable(cacheNames = CacheConstants.CFG_DATA_CACHE, 
                       keyGenerator = CacheConstants.CUSTOM_KEY_GENERATOR, 
                       sync = true)
            }
        )
    @Target({ ElementType.METHOD, ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface CfgDataCache {
    }
    
    @Mapper
    public interface SysConstantMapper {
    
        @CfgDataCache
        List<SysConstantDO> selectRecordsByQO(@Param("cond") SysConstantQO cond);
    }
    

    속성 설명
    sync 속성:
    캐 시 를 불 러 올 때 하나의 스 레 드 로 데 이 터 를 계산 하고 다른 스 레 드 가 막 힐 수 있 습 니 다.cafeine 자체 에 도 유사 한 메커니즘 이 있 지만sync속성 을 사용 합 니 다.다른 스 레 드 는 cafeine 이 아 닌 spring 으로 막 힙 니 다.cafeine 의 차단 메커니즘 에서 모든 막 힌 스 레 드 는'자 물 쇠 를 가 져 오고 캐 시 를 계산 하 며 자 물 쇠 를 방출 합 니 다'와 유사 한 과정 을 반복 해 야 하기 때문에 spring 이 막 히 고 막 힌 스 레 드 는 계산 데이터 의 스 레 드 가 캐 시 를 마 친 후에 캐 시 에서 데 이 터 를 직접 가 져 옵 니 다.
    sync 속성 과 unless 속성 은 공용 할 수 없습니다.
    Synchronize the invocation of the underlying method if several threads are attempting to load a value for the same key. The synchronization leads to a couple of limitations:
  • unless() is not supported
  • Only one cache may be specified
  • No other cache-related operation can be combined

  • This is effectively a hint and the actual cache provider that you are using may not support it in a synchronized fashion. Check your provider documentation for more details on the actual semantics.
    ​ —— javadoc
    unless 속성:
    캐 시 를 거부 하 는 데 사 용 됩 니 다.캐 시 계산 이 끝 난 후에 판단 합 니 다.이 표현 식 을 만족 시 키 면 계산 결 과 는 캐 시 에 추가 되 지 않 습 니 다.예 를 들 어unless = "#result == null"계산 결과 가 비어 있 으 면 캐 시 를 넣 지 않 는 다 는 뜻 이다.
    보충 설명
  • spring cache 는 하위 클래스 를 동적 으로 생 성 하 는 프 록 시 체 제 를 사용 하여 방법의 호출 을 절단면 으로 합 니 다.캐 시 방법 이 외부 참조 가 아 닌 내부 호출 이면 프 록 시 실패,절단면 이 실 효 됩 니 다.

  • 레 퍼 런 스
    1.spring-boot-features-caching-provider-caffeine
    2.ben-manes-caffeine
    3.미래의 캐 시 에서 깊이 복호화-cafeine
    4.카페인 캐 시
    5.다 중 스 레 드 높 은 동시 다발 장면 에서 자바 캐 시 문 제 를 어떻게 해결 합 니까?

    좋은 웹페이지 즐겨찾기