com.jarvis.cache.clone.ICloner中的Object deepClone(Object obj) 改为 Object deepClone(Object obj, final Type type),在能获得Type的情况下使用,能更好保证数据准备和效率
进一步优化深度复制功能,因为深度复制的目的主要是用于防止外部修改已经缓存的数据,对于一些不可变对象,就可以直接使用,不再走clone逻辑。
增加Jackson支持
将CacheKeyTO中所有属性改为final,同时删除fullKey属性。同时增加hashCode和equals两个方法的实现
修复DataLoader中,等待第一个请求获取数据后,又再去数据层获取数据的BUG,这个BUG是在4.11版本产生的,建议使用4.11和4.12的用户升级一下。
当遍历次数达到2000时,执行Thread.sleep(0); 触发操作系统立刻重新进行一次CPU竞争, 让其它线程获得CPU控制权的权力。
com.jarvis.cache.map.CachePointCut 做如下修改
AutoLoadHandler中排序线程增加sleep,以节约系统资源
将获取AOP配置信息功能从 AdminServlet 中抽取出来,并使用CacheManagerConfig接口来获取。
受网友Rekoe 将AutoLoadCache 和 nutz整合的启发(https://github.com/Rekoe/AutoLoadCache),将AutoLoadCache 中的AOP相关功能进行抽取,以达到可扩展
使用当前的ProcessingTO来做同步锁,把锁粒度降到了最低,以提升并发性能;删除并发线程的计数器;如果第一个线程执行时出现异常,那等待中的线程,也直接抛出异常,因为此时去执行DAO的出错的可能性非常大,会造成服务器压力过大。
“拿来主义”机制指的是,当有多个请求去获取同一个数据时,我们先让其中一个请求先去DAO中获取数据,并放到缓存中,其它请求则等它完成后,直接去缓存中获取数据,通过这种方式减轻DAO中的并发。
但经测试发现,刚往Reids中放的数据,立即去取是获取不到数据的(无法命中),测试代码已经放到cache-example 中。优化后的方案是,不从远程服务器获取,而是从本地内存中获取第一个请求返回的数据。减少并发的同时,还能减轻网络压力。
不再使用默认缓存Key,所有的缓存都必须自定义缓存Key;原来使用$hash()来调用hash函数,改为使用#hash()进行调用。
之前版本中使用通配符(?和*)进行批量删除缓存,这种方法性能比较差,需要多次与Redis进行交互,而且随着缓存Key的数量的增加,性能也会下降,如果有多个Reids实例的话,还需要遍历每个实例。为了解决这个问题,我们使用hash表保存需要批量删除的缓存,要批量删除缓存时,只要把hash表删除就可以了。
如果在开发阶段不想使用Redis来缓存数据,可以使用com.jarvis.cache.map.CachePointCut,把数据缓存到本地内存中,虽然它不支持使用通配符进行批量删除缓存,但同样支持使用hash表进行批量删除缓存。所以转用Redis缓存数据是没有任务问题的。
如果需要在MyBatis Mapper中使用@Cache和@CacheDelete,则需要使用com.jarvis.cache.mybatis.CachePointCutProxy 来处理。
由于我们这里要实现的功能是,当前的线程要等待前一个正在运行线程的结果,但我们不知道前一个线程的执行到哪一步。有可能在我们要执行wait时,已经完成notifyAll了。通过调整逻辑变得更加严谨。
Boolean isProcessing=null;
try {
lock.lock();
if(null == (isProcessing=processing.get(cacheKey))) {// 为发减少数据层的并发,增加等待机制。
processing.put(cacheKey, Boolean.TRUE);
}
} finally {
lock.unlock();
}
改为:
Boolean isProcessing=processing.putIfAbsent(cacheKey, Boolean.TRUE);// 为发减少数据层的并发,增加等待机制。
@Cache(expire=0, waitTimeOut=500),当expire=0时,将设置为永久缓存;waitTimeOut 用于设置并发等待时间(毫秒)。
增加自动加载,单个线程内的等待时间间隔:
<bean id="autoLoadConfig" class="com.jarvis.cache.to.AutoLoadConfig">
... ...
<property name="autoLoadPeriod" value="50" /><!--默认值50ms-->
</bean>
优化AbstractCacheManager类的loadData方法中线程同步锁。
####2.2 解决Hessian不能正确序列化BigDecimal问题
<bean id="jdkSerializer" class="com.jarvis.cache.serializer.JdkSerializer" />
<bean id="hessianSerializer" class="com.jarvis.cache.serializer.HessianSerializer" />
<bean id="cachePointCut" class="com.jarvis.cache.redis.ShardedCachePointCut" destroy-method="destroy">
<constructor-arg ref="autoLoadConfig" />
<property name="serializer" ref="hessianSerializer" />
<property name="shardedJedisPool" ref="shardedJedisPool" />
<property name="namespace" value="test" />
</bean>
虽然Kryo效率比较高,但使用Kryo会出现的问题比较多,所以还是慎重使用,系统经常维护的就不太适合使用,经过测试,改变属性名称,或删除中间的属性等情况都可能反序列出错误的值,所以如果遇到有减少或修改的情况要及时清里缓存。如果是增加属性则会反序列化失败,这正符合我们的要求。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。