JetCache是由阿里巴巴开源的一个通用缓存访问框架,它提供了简洁而强大的缓存管理功能。JetCache具有丰富的特性,使其在许多场景中比Spring Cache更为便捷和高效。

缓存类型

最常用的使用场景:
 
在JetCache中,缓存类型主要有三种选择:LOCALREMOTEBOTH。它们分别对应本地内存缓存、远程缓存服务器(如Redis)以及两级缓存。根据具体应用场景,合理选择缓存类型可以显著降低缓存服务器的压力,同时提升服务的响应时间。
在正常业务场景,一般都先使用REMOTE 缓存,使用redis缓存,适用于多节点的分布式系统,而且如果缓存有问题可以方便删除和修正。当请求量上来时候,再将REMOTE 改为BOTH ,这样可以直接使用本地缓存,提高吞吐。
但是直接这样直接该类型也是会有问题的,最近就遇到了一个案例。
看下代码demo
REMOTE缓存,存了List的数据,然后在业务层使用了 Collections.sort 进行排序。
当将REMOTE 改为BOTH 后,概率报 ConcurrentModificationException 异常。
notion image
因为在本地缓存中,缓存的是同一个对象,在高并发场景,比如同一时刻多个请求打入,刚好取获取了同一个对象 sort 操作。
抽象出该场景后的demo代码
将三种类型缓存做个测试demo
可以看到,BOTH 和 LOCAL 都会出现 ConcurrentModificationException 异常。
notion image
notion image
本地缓存配置由 LinkedHashMap 改为 Caffeine 也是一样的,Caffeine底层也是使用Map存储本地对象。
所以,在这种场景使用本地缓存时,要么讲存入List排完序之后再缓存起来,要么在排序时候加锁或者用synchronized块保证线程安全。

序列化

默认情况下,jetcache使用的序列化器都是java,它性能最差,但是兼容性最好。
在redis中的缓存如下
notion image
那可不可以将值序列化成JSON格式,方便阅读?
在jetcache2.7中,已经增加了fastjson2序列化器的支持。但是
json不是一个专门的java序列化库,更多的时候是用来和前端进行数据交互,前端传入的 不受信任的json字符串如果随便就反序列化,会造成极其严重的安全问题,为了避免这些问题各个json类库都变得极为保守, 只要反射无法识别类型(比如字段类型是Object实际上是XxxBean),就会反序列化为JSONObject,这样反序列化的兼容性就变得很差。
所以官方默认是没有将fastjson2序列化器注册的,我们在工程中可以自己注册并修改配置。设置参考:
 
这时候redis中的缓存值如下
notion image
 
顺便看下使用 kryo5 序列化器的redis缓存值
notion image
 

参考资料

MYSQL的深度分页问题Java 时间本地化,时区数据库更新
Loading...