• 【SpringBoot整合缓存】-----jetcache以及j2cache篇


    本专栏将从基础开始,循序渐进,以实战为线索,逐步深入SpringBoot相关知识相关知识,打造完整的SpringBoot学习步骤,提升工程化编码能力和思维能力,写出高质量代码。希望大家都能够从中有所收获,也请大家多多支持。
    专栏地址:SpringBoot专栏
    本文涉及的代码都已放在gitee上:gitee地址
    如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。
    专栏汇总:专栏汇总

    SpringBoot整合jetcache缓存

    ​ 目前我们使用的缓存都是要么A要么B,能不能AB一起用呢?这一节就解决这个问题。springboot针对缓存的整合仅仅停留在用缓存上面,如果缓存自身不支持同时支持AB一起用,springboot也没办法,所以要想解决AB缓存一起用的问题,就必须找一款缓存能够支持AB两种缓存一起用,有这种缓存吗?还真有,阿里出品,jetcache。

    ​ jetcache严格意义上来说,并不是一个缓存解决方案,只能说他算是一个缓存框架,然后把别的缓存放到jetcache中管理,这样就可以支持AB缓存一起用了。并且jetcache参考了springboot整合缓存的思想,整体技术使用方式和springboot的缓存解决方案思想非常类似。下面咱们就先把jetcache用起来,然后再说它里面的一些小的功能。

    ​ 做之前要先明确一下,jetcache并不是随便拿两个缓存都能拼到一起去的。目前jetcache支持的缓存方案本地缓存支持两种,远程缓存支持两种,分别如下:

    • 本地缓存(Local)
      • LinkedHashMap
      • Caffeine
    • 远程缓存(Remote)
      • Redis
      • Tair

    ​ 为什么jetcache只支持2+2这么4款缓存呢?阿里研发这个技术其实主要是为了满足自身的使用需要。最初肯定只有1+1种,逐步变化成2+2种。下面就以LinkedHashMap+Redis的方案实现本地与远程缓存方案同时使用。

    纯远程方案

    步骤①:导入springboot整合jetcache对应的坐标starter,当前坐标默认使用的远程方案是redis

    <dependency>
        <groupId>com.alicp.jetcache</groupId>
        <artifactId>jetcache-starter-redis</artifactId>
        <version>2.6.2</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    步骤②:远程方案基本配置

    jetcache:
      remote:
        default:
          type: redis
          host: localhost
          port: 6379
    #  由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换
          keyCovertor: fastjson
          valueEncode: java
          valueDecode: java
          poolconfig:
            maxTotal: 50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ​ 其中poolConfig是必配项,否则会报错

    步骤③:启用缓存,在引导类上方标注注解@EnableCreateCacheAnnotation配置springboot程序中可以使用注解的形式创建缓存

    @SpringBootApplication
    //jetcache启用缓存的主开关
    @EnableCreateCacheAnnotation
    public class Springboot20JetCacheApplication {
        public static void main(String[] args) {
            SpringApplication.run(Springboot20JetCacheApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    步骤④:创建缓存对象Cache,并使用注解@CreateCache标记当前缓存的信息,然后使用Cache对象的API操作缓存,put写缓存,get读缓存。

    @Service
    public class SMSCodeServiceImpl implements SMSCodeService {
        @Autowired
        private CodeUtils codeUtils;
        
        @CreateCache(name="jetCache_",expire = 10,timeUnit = TimeUnit.SECONDS)
        private Cache<String ,String> jetCache;
    
        public String sendCodeToSMS(String tele) {
            String code = codeUtils.generator(tele);
            jetCache.put(tele,code);
            return code;
        }
    
        public boolean checkCode(SMSCode smsCode) {
            String code = jetCache.get(smsCode.getTele());
            return smsCode.getCode().equals(code);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    ​ 通过上述jetcache使用远程方案连接redis可以看出,jetcache操作缓存时的接口操作更符合开发者习惯,使用缓存就先获取缓存对象Cache,放数据进去就是put,取数据出来就是get,更加简单易懂。并且jetcache操作缓存时,可以为某个缓存对象设置过期时间,将同类型的数据放入缓存中,方便有效周期的管理。

    ​ 上述方案中使用的是配置中定义的default缓存,其实这个default是个名字,可以随便写,也可以随便加。例如再添加一种缓存解决方案,参照如下配置进行:

    jetcache:
      remote:
        default:
          type: redis
          host: localhost
          port: 6379
    #  由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换
          keyCovertor: fastjson
          valueEncode: java
          valueDecode: java
          poolconfig:
            maxTotal: 50
        sms:
          type: redis
          host: localhost
          port: 6379
    #  由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换
          keyCovertor: fastjson
          valueEncode: java
          valueDecode: java
          poolconfig:
            maxTotal: 50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    ​ 如果想使用名称是sms的缓存,需要再创建缓存时指定参数area,声明使用对应缓存即可

    @Service
    public class SMSCodeServiceImpl implements SMSCodeService {
        @Autowired
        private CodeUtils codeUtils;
        
        @CreateCache(area="sms",name="jetCache_",expire = 10,timeUnit = TimeUnit.SECONDS)
        private Cache<String ,String> jetCache;
    
        public String sendCodeToSMS(String tele) {
            String code = codeUtils.generator(tele);
            jetCache.put(tele,code);
            return code;
        }
    
        public boolean checkCode(SMSCode smsCode) {
            String code = jetCache.get(smsCode.getTele());
            return smsCode.getCode().equals(code);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    纯本地方案

    ​ 远程方案中,配置中使用remote表示远程,换成local就是本地,只不过类型不一样而已。

    步骤①:导入springboot整合jetcache对应的坐标starter

    <dependency>
        <groupId>com.alicp.jetcache</groupId>
        <artifactId>jetcache-starter-redis</artifactId>
        <version>2.6.2</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    步骤②:本地缓存基本配置

    jetcache:
      local:
        default:
          type: linkedhashmap
          keyConvertor: fastjson
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ​ 为了加速数据获取时key的匹配速度,jetcache要求指定key的类型转换器。简单说就是,如果你给了一个Object作为key的话,我先用key的类型转换器给转换成字符串,然后再保存。等到获取数据时,仍然是先使用给定的Object转换成字符串,然后根据字符串匹配。由于jetcache是阿里的技术,这里推荐key的类型转换器使用阿里的fastjson。

    步骤③:启用缓存

    @SpringBootApplication
    //jetcache启用缓存的主开关
    @EnableCreateCacheAnnotation
    public class Springboot20JetCacheApplication {
        public static void main(String[] args) {
            SpringApplication.run(Springboot20JetCacheApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    步骤④:创建缓存对象Cache时,标注当前使用本地缓存

    @Service
    public class SMSCodeServiceImpl implements SMSCodeService {
        @CreateCache(name="jetCache_",expire = 1000,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.LOCAL)
        private Cache<String ,String> jetCache;
    
        public String sendCodeToSMS(String tele) {
            String code = codeUtils.generator(tele);
            jetCache.put(tele,code);
            return code;
        }
    
        public boolean checkCode(SMSCode smsCode) {
            String code = jetCache.get(smsCode.getTele());
            return smsCode.getCode().equals(code);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ​ cacheType控制当前缓存使用本地缓存还是远程缓存,配置cacheType=CacheType.LOCAL即使用本地缓存。

    本地+远程方案

    ​ 本地和远程方法都有了,两种方案一起使用如何配置呢?其实就是将两种配置合并到一起就可以了。

    jetcache:
      local:
        default:
          type: linkedhashmap
          keyConvertor: fastjson
      remote:
        default:
          type: redis
          host: localhost
          port: 6379
    #  由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换
          keyCovertor: fastjson
          valueEncode: java
          valueDecode: java
          poolconfig:
            maxTotal: 50
        sms:
          type: redis
          host: localhost
          port: 6379
    #  由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换
          keyCovertor: fastjson
          valueEncode: java
          valueDecode: java
          poolconfig:
            maxTotal: 50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    ​ 在创建缓存的时候,配置cacheType为BOTH即则本地缓存与远程缓存同时使用。

    @Service
    public class SMSCodeServiceImpl implements SMSCodeService {
        @CreateCache(name="jetCache_",expire = 1000,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.BOTH)
        private Cache<String ,String> jetCache;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ​ cacheType如果不进行配置,默认值是REMOTE,即仅使用远程缓存方案。关于jetcache的配置,参考以下信息

    属性默认值说明
    jetcache.statIntervalMinutes0统计间隔,0表示不统计
    jetcache.hiddenPackages自动生成name时,隐藏指定的包名前缀
    jetcache.[local|remote].${area}.type缓存类型,本地支持linkedhashmap、caffeine,远程支持redis、tair
    jetcache.[local|remote].${area}.keyConvertorkey转换器,当前仅支持fastjson
    jetcache.[local|remote].${area}.valueEncoderjava仅remote类型的缓存需要指定,可选java和kryo
    jetcache.[local|remote].${area}.valueDecoderjava仅remote类型的缓存需要指定,可选java和kryo
    jetcache.[local|remote].${area}.limit100仅local类型的缓存需要指定,缓存实例最大元素数
    jetcache.[local|remote].${area}.expireAfterWriteInMillis无穷大默认过期时间,毫秒单位
    jetcache.local.${area}.expireAfterAccessInMillis0仅local类型的缓存有效,毫秒单位,最大不活动间隔

    ​ 以上方案仅支持手工控制缓存,但是springcache方案中的方法缓存特别好用,给一个方法添加一个注解,方法就会自动使用缓存。jetcache也提供了对应的功能,即方法缓存。

    Jetcache方法缓存

    ​ jetcache提供了方法缓存方案,只不过名称变更了而已。在对应的操作接口上方使用注解@Cached即可

    步骤①:导入springboot整合jetcache对应的坐标starter

    <dependency>
        <groupId>com.alicp.jetcache</groupId>
        <artifactId>jetcache-starter-redis</artifactId>
        <version>2.6.2</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    步骤②:配置缓存

    jetcache:
      local:
        default:
          type: linkedhashmap
          keyConvertor: fastjson
      remote:
        default:
          type: redis
          host: localhost
          port: 6379
          keyConvertor: fastjson
          valueEncode: java
          valueDecode: java
    #  由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换
          keyCovertor: fastjson
          valueEncode: java
          valueDecode: java
          poolconfig:
            maxTotal: 50
        sms:
          type: redis
          host: localhost
          port: 6379
    #  由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换
          keyCovertor: fastjson
          valueEncode: java
          valueDecode: java
          poolconfig:
            maxTotal: 50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    ​ 由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换。需要配置keyConvertor表示key的类型转换方式,同时标注value的转换类型方式,值进入redis时是java类型,标注valueEncode为java,值从redis中读取时转换成java,标注valueDecode为java。

    ​ 注意,为了实现Object类型的值进出redis,需要保障进出redis的Object类型的数据必须实现序列化接口。

    @Data
    public class Book implements Serializable {
        private Integer id;
        private String type;
        private String name;
        private String description;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    步骤③:启用缓存时开启方法缓存功能,并配置basePackages,说明在哪些包中开启方法缓存

    @SpringBootApplication
    //jetcache启用缓存的主开关
    @EnableCreateCacheAnnotation
    //开启方法注解缓存
    @EnableMethodCache(basePackages = "com.hashnode")
    public class Springboot20JetCacheApplication {
        public static void main(String[] args) {
            SpringApplication.run(Springboot20JetCacheApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    步骤④:使用注解@Cached标注当前方法使用缓存

    @Service
    public class BookServiceImpl implements BookService {
        @Autowired
        private BookDao bookDao;
        
        @Override
        @Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.REMOTE)
        public Book getById(Integer id) {
            return bookDao.selectById(id);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    远程方案的数据同步

    ​ 由于远程方案中redis保存的数据可以被多个客户端共享,这就存在了数据同步问题。jetcache提供了3个注解解决此问题,分别在更新、删除操作时同步缓存数据,和读取缓存时定时刷新数据

    更新缓存

    @CacheUpdate(name="book_",key="#book.id",value="#book")
    public boolean update(Book book) {
        return bookDao.updateById(book) > 0;
    }
    
    • 1
    • 2
    • 3
    • 4

    删除缓存

    @CacheInvalidate(name="book_",key = "#id")
    public boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }
    
    • 1
    • 2
    • 3
    • 4

    定时刷新缓存

    @Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.REMOTE)
    //    5s刷新一次
    @CacheRefresh(refresh = 5)
    public Book getById(Integer id) {
        return bookDao.selectById(id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    数据报表

    ​ jetcache还提供有简单的数据报表功能,帮助开发者快速查看缓存命中信息,只需要添加一个配置即可

    jetcache:
      statIntervalMinutes: 1
    
    • 1
    • 2

    ​ 设置后,每1分钟在控制台输出缓存数据命中信息

    [DefaultExecutor] c.alicp.jetcache.support.StatInfoLogger  : jetcache stat from 2022-02-28 09:32:15,892 to 2022-02-28 09:33:00,003
    cache    |    qps|   rate|   get|    hit|   fail|   expire|   avgLoadTime|   maxLoadTime
    ---------+-------+-------+------+-------+-------+---------+--------------+--------------
    book_    |   0.66| 75.86%|    29|     22|      0|        0|          28.0|           188
    ---------+-------+-------+------+-------+-------+---------+--------------+--------------
    
    • 1
    • 2
    • 3
    • 4
    • 5

    总结

    1. jetcache是一个类似于springcache的缓存解决方案,自身不具有缓存功能,它提供有本地缓存与远程缓存多级共同使用的缓存解决方案
    2. jetcache提供的缓存解决方案受限于目前支持的方案,本地缓存支持两种,远程缓存支持两种
    3. 注意数据进入远程缓存时的类型转换问题
    4. jetcache提供方法缓存,并提供了对应的缓存更新与刷新功能
    5. jetcache提供有简单的缓存信息命中报表方便开发者即时监控缓存数据命中情况

    思考

    ​ jetcache解决了前期使用缓存方案单一的问题,但是仍然不能灵活的选择缓存进行搭配使用,是否存在一种技术可以灵活的搭配各种各样的缓存使用呢?有,咱们下一节再讲。

    SpringBoot整合j2cache缓存

    ​ jetcache可以在限定范围内构建多级缓存,但是灵活性不足,不能随意搭配缓存,本节介绍一种可以随意搭配缓存解决方案的缓存整合框架,j2cache。下面就来讲解如何使用这种缓存框架,以Ehcache与redis整合为例:

    步骤①:导入j2cache、redis、ehcache坐标

    <dependency>
        <groupId>net.oschina.j2cache</groupId>
        <artifactId>j2cache-core</artifactId>
        <version>2.8.4-release</version>
    </dependency>
    <dependency>
        <groupId>net.oschina.j2cache</groupId>
        <artifactId>j2cache-spring-boot2-starter</artifactId>
        <version>2.8.0-release</version>
    </dependency>
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ​ j2cache的starter中默认包含了redis坐标,官方推荐使用redis作为二级缓存,因此此处无需导入redis坐标

    步骤②:配置一级与二级缓存,并配置一二级缓存间数据传递方式,配置书写在名称为j2cache.properties的文件中。如果使用ehcache还需要单独添加ehcache的配置文件

    # 1级缓存
    j2cache.L1.provider_class = ehcache
    ehcache.configXml = ehcache.xml
    
    # 2级缓存
    j2cache.L2.provider_class = net.oschina.j2cache.cache.support.redis.SpringRedisProvider
    j2cache.L2.config_section = redis
    redis.hosts = localhost:6379
    
    # 1级缓存中的数据如何到达二级缓存
    j2cache.broadcast = net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ​ 此处配置不能乱配置,需要参照官方给出的配置说明进行。例如1级供应商选择ehcache,供应商名称仅仅是一个ehcache,但是2级供应商选择redis时要写专用的Spring整合Redis的供应商类名SpringRedisProvider,而且这个名称并不是所有的redis包中能提供的,也不是spring包中提供的。因此配置j2cache必须参照官方文档配置,而且还要去找专用的整合包,导入对应坐标才可以使用。

    ​ 一级与二级缓存最重要的一个配置就是两者之间的数据沟通方式,此类配置也不是随意配置的,并且不同的缓存解决方案提供的数据沟通方式差异化很大,需要查询官方文档进行设置。

    步骤③:使用缓存

    @Service
    public class SMSCodeServiceImpl implements SMSCodeService {
        @Autowired
        private CodeUtils codeUtils;
    
        @Autowired
        private CacheChannel cacheChannel;
    
        public String sendCodeToSMS(String tele) {
            String code = codeUtils.generator(tele);
            cacheChannel.set("sms",tele,code);
            return code;
        }
    
        public boolean checkCode(SMSCode smsCode) {
            String code = cacheChannel.get("sms",smsCode.getTele()).asString();
            return smsCode.getCode().equals(code);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    ​ j2cache的使用和jetcache比较类似,但是无需开启使用的开关,直接定义缓存对象即可使用,缓存对象名CacheChannel。

    ​ j2cache的使用不复杂,配置是j2cache的核心,毕竟是一个整合型的缓存框架。缓存相关的配置过多,可以查阅j2cache-core核心包中的j2cache.properties文件中的说明。如下:

    #J2Cache configuration
    #########################################
    # Cache Broadcast Method
    # values:
    # jgroups -> use jgroups's multicast
    # redis -> use redis publish/subscribe mechanism (using jedis)
    # lettuce -> use redis publish/subscribe mechanism (using lettuce, Recommend)
    # rabbitmq -> use RabbitMQ publisher/consumer mechanism
    # rocketmq -> use RocketMQ publisher/consumer mechanism
    # none -> don't notify the other nodes in cluster
    # xx.xxxx.xxxx.Xxxxx your own cache broadcast policy classname that implement net.oschina.j2cache.cluster.ClusterPolicy
    #########################################
    j2cache.broadcast = redis
    
    # jgroups properties
    jgroups.channel.name = j2cache
    jgroups.configXml = /network.xml
    
    # RabbitMQ properties
    rabbitmq.exchange = j2cache
    rabbitmq.host = localhost
    rabbitmq.port = 5672
    rabbitmq.username = guest
    rabbitmq.password = guest
    
    # RocketMQ properties
    rocketmq.name = j2cache
    rocketmq.topic = j2cache
    # use ; to split multi hosts
    rocketmq.hosts = 127.0.0.1:9876
    
    #########################################
    # Level 1&2 provider
    # values:
    # none -> disable this level cache
    # ehcache -> use ehcache2 as level 1 cache
    # ehcache3 -> use ehcache3 as level 1 cache
    # caffeine -> use caffeine as level 1 cache(only in memory)
    # redis -> use redis as level 2 cache (using jedis)
    # lettuce -> use redis as level 2 cache (using lettuce)
    # readonly-redis -> use redis as level 2 cache ,but never write data to it. if use this provider, you must uncomment `j2cache.L2.config_section` to make the redis configurations available.
    # memcached -> use memcached as level 2 cache (xmemcached),
    # [classname] -> use custom provider
    #########################################
    
    j2cache.L1.provider_class = caffeine
    j2cache.L2.provider_class = redis
    
    # When L2 provider isn't `redis`, using `L2.config_section = redis` to read redis configurations
    # j2cache.L2.config_section = redis
    
    # Enable/Disable ttl in redis cache data (if disabled, the object in redis will never expire, default:true)
    # NOTICE: redis hash mode (redis.storage = hash) do not support this feature)
    j2cache.sync_ttl_to_redis = true
    
    # Whether to cache null objects by default (default false)
    j2cache.default_cache_null_object = true
    
    #########################################
    # Cache Serialization Provider
    # values:
    # fst -> using fast-serialization (recommend)
    # kryo -> using kryo serialization
    # json -> using fst's json serialization (testing)
    # fastjson -> using fastjson serialization (embed non-static class not support)
    # java -> java standard
    # fse -> using fse serialization
    # [classname implements Serializer]
    #########################################
    
    j2cache.serialization = json
    #json.map.person = net.oschina.j2cache.demo.Person
    
    #########################################
    # Ehcache configuration
    #########################################
    
    # ehcache.configXml = /ehcache.xml
    
    # ehcache3.configXml = /ehcache3.xml
    # ehcache3.defaultHeapSize = 1000
    
    #########################################
    # Caffeine configuration
    # caffeine.region.[name] = size, xxxx[s|m|h|d]
    #
    #########################################
    caffeine.properties = /caffeine.properties
    
    #########################################
    # Redis connection configuration
    #########################################
    
    #########################################
    # Redis Cluster Mode
    #
    # single -> single redis server
    # sentinel -> master-slaves servers
    # cluster -> cluster servers (数据库配置无效,使用 database = 0)
    # sharded -> sharded servers  (密码、数据库必须在 hosts 中指定,且连接池配置无效 ; redis://user:password@127.0.0.1:6379/0)
    #
    #########################################
    
    redis.mode = single
    
    #redis storage mode (generic|hash)
    redis.storage = generic
    
    ## redis pub/sub channel name
    redis.channel = j2cache
    ## redis pub/sub server (using redis.hosts when empty)
    redis.channel.host =
    
    #cluster name just for sharded
    redis.cluster_name = j2cache
    
    ## redis cache namespace optional, default[empty]
    redis.namespace =
    
    ## redis command scan parameter count, default[1000]
    #redis.scanCount = 1000
    
    ## connection
    # Separate multiple redis nodes with commas, such as 192.168.0.10:6379,192.168.0.11:6379,192.168.0.12:6379
    
    redis.hosts = 127.0.0.1:6379
    redis.timeout = 2000
    redis.password =
    redis.database = 0
    redis.ssl = false
    
    ## redis pool properties
    redis.maxTotal = 100
    redis.maxIdle = 10
    redis.maxWaitMillis = 5000
    redis.minEvictableIdleTimeMillis = 60000
    redis.minIdle = 1
    redis.numTestsPerEvictionRun = 10
    redis.lifo = false
    redis.softMinEvictableIdleTimeMillis = 10
    redis.testOnBorrow = true
    redis.testOnReturn = false
    redis.testWhileIdle = true
    redis.timeBetweenEvictionRunsMillis = 300000
    redis.blockWhenExhausted = false
    redis.jmxEnabled = false
    
    #########################################
    # Lettuce scheme
    #
    # redis -> single redis server
    # rediss -> single redis server with ssl
    # redis-sentinel -> redis sentinel
    # redis-cluster -> cluster servers
    #
    #########################################
    
    #########################################
    # Lettuce Mode
    #
    # single -> single redis server
    # sentinel -> master-slaves servers
    # cluster -> cluster servers (数据库配置无效,使用 database = 0)
    # sharded -> sharded servers  (密码、数据库必须在 hosts 中指定,且连接池配置无效 ; redis://user:password@127.0.0.1:6379/0)
    #
    #########################################
    
    ## redis command scan parameter count, default[1000]
    #lettuce.scanCount = 1000
    lettuce.mode = single
    lettuce.namespace =
    lettuce.storage = hash
    lettuce.channel = j2cache
    lettuce.scheme = redis
    lettuce.hosts = 127.0.0.1:6379
    lettuce.password =
    lettuce.database = 0
    lettuce.sentinelMasterId =
    lettuce.maxTotal = 100
    lettuce.maxIdle = 10
    lettuce.minIdle = 10
    # timeout in milliseconds
    lettuce.timeout = 10000
    # redis cluster topology refresh interval in milliseconds
    lettuce.clusterTopologyRefresh = 3000
    
    #########################################
    # memcached server configurations
    # refer to https://gitee.com/mirrors/XMemcached
    #########################################
    
    memcached.servers = 127.0.0.1:11211
    memcached.username =
    memcached.password =
    memcached.connectionPoolSize = 10
    memcached.connectTimeout = 1000
    memcached.failureMode = false
    memcached.healSessionInterval = 1000
    memcached.maxQueuedNoReplyOperations = 100
    memcached.opTimeout = 100
    memcached.sanitizeKeys = false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201

    总结

    1. j2cache是一个缓存框架,自身不具有缓存功能,它提供多种缓存整合在一起使用的方案
    2. j2cache需要通过复杂的配置设置各级缓存,以及缓存之间数据交换的方式
    3. j2cache操作接口通过CacheChannel实现
  • 相关阅读:
    Android修行手册-Gson中不用实体类生成JsonObject或JsonArray
    纯干货:准备输入文件 | VASP零基础保姆级指南
    【新增功能已上线】jvs-rlues(规则引擎)及智能bi本周更新
    【算能】在Docker中调用PCIe卡
    Go语言聊天室demo
    使用SimpleITK批量计算医学图像分割的mask体积,病灶体积
    Dinky上路之旅
    内存快照:宕机后,Redis如何实现快速恢复?
    FFplay文档解读-46-视频源,视频接收器
    Java面试题大全、题+详细解答(2022版)
  • 原文地址:https://blog.csdn.net/Learning_xzj/article/details/125510945