com.alicp.jetcache.CacheConfigException: no remote cache builder: default的问题 >>> 见黄色字体

com.alicp.jetcache.CacheConfigException: no localcache builder: default

查阅搜索,并给自己的整理记录:
阿里开源项目Jetcache:https://github.com/alibaba/jetcache
WIKI中文Docs:https://github.com/alibaba/jetcache/wiki/Home_CN

一、pom依赖

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>2.6.0</version>
</dependency>

二、yml配置

jetcache:
  statIntervalMinutes: 15
  areaInCacheName: false
  hiddenPackages: com.sqc #隐藏包名
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      keyConvertor: fastjson
      valueEncoder: java
      valueDecoder: java
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: 127.0.0.1
      port: 6379

注意:yml配置中jetcache与spring对齐!!(找了半天这个错误,一直没有初始化init cache)

三、启动类配置

@SpringBootApplication
@EnableMethodCache(basePackages = "com.sqc") // 扫包,使@Cache生效
@EnableCreateCacheAnnotation    // 使@CreateCache生效
public class MySpringBootApp {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApp.class);
    }
}

注解使用:方法

在spring环境下,使用@Cached注解可以为一个方法添加缓存,@CacheUpdate用于更新缓存,@CacheInvalidate用于移除缓存元素。注解可以加在接口上也可以加在类上,加注解的类必须是一个spring bean,例如:

public interface UserService {

    @Cached(name="userCache.", key="#userId", expire = 3600)
    User getUserById(long userId);
 
    @CacheUpdate(name="userCache.", key="#user.userId", value="#user")
    void updateUser(User user);
 
    @CacheInvalidate(name="userCache.", key="#userId")
    void deleteUser(long userId);
    
}

注解使用:变量对象@CreateCache

public class GatewayRouteService extends ServiceImpl<GatewayRouteMapper, GatewayRoute> implements IGatewayRouteService {

    private static final String GATEWAY_ROUTES = "gateway_routes::";

    @CreateCache(name = GATEWAY_ROUTES, cacheType = CacheType.REMOTE)
    private Cache<String, RouteDefinition> gatewayRouteCache;
    
    void save (RouteDefinition routeDefinition) {
        String id = "111";
        gatewayRouteCache.put(id, routeDefinition);
    }
}

用代码使用

    GenericObjectPoolConfig pc = new GenericObjectPoolConfig();
    pc.setMinIdle(2);
    pc.setMaxIdle(10);
    pc.setMaxTotal(10);
    JedisPool pool = new JedisPool(pc, "localhost", 6379);
    Cache<String, Goods> goodsCache = RedisCacheBuilder.createRedisCacheBuilder()
            .keyConvertor(FastjsonKeyConvertor.INSTANCE)
            .valueEncoder(JavaValueEncoder.INSTANCE)
            .valueDecoder(JavaValueDecoder.INSTANCE)
            .jedisPool(pool)
            .keyPrefix("goodsCache-")
            .expireAfterWrite(200, TimeUnit.SECONDS)
            .buildCache();

spring boot环境下的lettuce支持

jetcache: 
  areaInCacheName: false
  remote:
    default:
      type: redis.lettuce
      keyConvertor: fastjson
      uri: redis://127.0.0.1:6379/

如果使用sentinel做自动主备切换,uri可以配置为redis-sentinel://127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381/?sentinelMasterId=mymaster

  #sentinels: 127.0.0.1:26379 , 127.0.0.1:26380, 127.0.0.1:26381
  #masterName: mymaster

logger输出统计信息

当yml中的jetcache.statIntervalMinutes大于0时,通过@CreateCache和@Cached配置出来的Cache自带监控。JetCache会按指定的时间定期通过logger输出统计信息。默认输出信息类似如下:

2021-04-30 14:33:00.034  INFO 18852 --- [DefaultExecutor] c.alicp.jetcache.support.StatInfoLogger  : jetcache stat from 2021-04-30 14:32:44,790 to 2021-04-30 14:33:00,006
cache        |       qps|   rate|           get|           hit|          fail|        expire|avgLoadTime|maxLoadTime
-------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------
goods-       |      0.00|  0.00%|             0|             0|             0|             0|        0.0|          0
goods-_local |      0.00|  0.00%|             0|             0|             0|             0|        0.0|          0
goods-_remote|      0.00|  0.00%|             0|             0|             0|             0|        0.0|          0
goods::      |      0.00|  0.00%|             0|             0|             0|             0|      263.0|        263
-------------+----------+-------+--------------+--------------+--------------+--------------+-----------+-----------

只有使用computeIfAbsent方法或者@Cached注解才会统计loadTime。用get方法取缓存,没有命中的话自己去数据库load,显然是无法统计到的。

如果需要定制输出,可以这样做:

@Bean
public SpringConfigProvider springConfigProvider() {
    return new SpringConfigProvider(){
        public Consumer<StatInfo> statCallback() {
            // return new StatInfoLogger(false);
            ... // 实现自己的logger
        }
    };
}

<appender name="JETCACHE_LOGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>jetcache.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>jetcache.log.%d{yyyy-MM-dd}</fileNamePattern>
        <maxHistory>30</maxHistory>
    </rollingPolicy>
 
    <encoder>
        <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
</appender>
 
<logger name="com.alicp.jetcache" level="INFO" additivity="false">
    <appender-ref ref="JETCACHE_LOGFILE" />
</logger>

其他:

jetcache:
  statIntervalMinutes: 15
  areaInCacheName: false
  hiddenPackages: com.alibaba
  local:
    default:
      type: caffeine
      limit: 100
      keyConvertor: fastjson
      expireAfterWriteInMillis: 100000
    otherArea:
      type: linkedhashmap
      limit: 100
      keyConvertor: none
      expireAfterWriteInMillis: 100000
  remote:
    default:
      type: redis
      keyConvertor: fastjson
      valueEncoder: java
      valueDecoder: java
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: ${redis.host}
      port: ${redis.port}
    otherArea:
      type: redis
      keyConvertor: fastjson
      valueEncoder: kryo
      valueDecoder: kryo
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: ${redis.host}
      port: ${redis.port}
属性默认值说明
jetcache.statIntervalMinutes0统计间隔,0表示不统计
jetcache.areaInCacheNametruejetcache-anno把cacheName作为远程缓存key前缀,2.4.3以前的版本总是把areaName加在cacheName中,因此areaName也出现在key前缀中。2.4.4以后可以配置,为了保持远程key兼容默认值为true,但是新项目的话false更合理些。
jetcache.hiddenPackages@Cached和@CreateCache自动生成name的时候,为了不让name太长,hiddenPackages指定的包名前缀被截掉
jetcache.[local|remote].${area}.type缓存类型。tair、redis为当前支持的远程缓存;linkedhashmap、caffeine为当前支持的本地缓存类型
jetcache.[local|remote].${area}.keyConvertorkey转换器的全局配置,当前只有一个已经实现的keyConvertor:fastjson。仅当使用@CreateCache且缓存类型为LOCAL时可以指定为none,此时通过equals方法来识别key。方法缓存必须指定keyConvertor
jetcache.[local|remote].${area}.valueEncoderjava序列化器的全局配置。仅remote类型的缓存需要指定,可选java和kryo
jetcache.[local|remote].${area}.valueDecoderjava序列化器的全局配置。仅remote类型的缓存需要指定,可选java和kryo
jetcache.[local|remote].${area}.limit100每个缓存实例的最大元素的全局配置,仅local类型的缓存需要指定。注意是每个缓存实例的限制,而不是全部,比如这里指定100,然后用@CreateCache创建了两个缓存实例(并且注解上没有设置localLimit属性),那么每个缓存实例的限制都是100
jetcache.[local|remote].${area}.expireAfterWriteInMillis无穷大以毫秒为单位指定超时时间的全局配置(以前为defaultExpireInMillis)
jetcache.local.${area}.expireAfterAccessInMillis0需要jetcache2.2以上,以毫秒为单位,指定多长时间没有访问,就让缓存失效,当前只有本地缓存支持。0表示不使用这个功能。

上表中${area}对应@Cached和@CreateCache的area属性。注意如果注解上没有指定area,默认值是"default"。

关于缓存的超时时间,有多个地方指定,澄清说明一下:

put等方法上指定了超时时间,则以此时间为准
put等方法上未指定超时时间,使用Cache实例的默认超时时间
Cache实例的默认超时时间,通过在@CreateCache和@Cached上的expire属性指定,如果没有指定,使用yml中定义的全局配置,例如@Cached(cacheType=local)使用jetcache.local.default.expireAfterWriteInMillis,如果仍未指定则是无穷大

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐