CacheBuilder.newBuilder() 使用cache机制

cache用来比如对于同样一次输入不止一次的取值的时候,使用缓存。

公司使用cache进行缓存token,时效一天,但是经常过期,找不到原因,故来学习一下缓存机制。

使用的是guava本地缓存,并没有使用redis作为缓存机制

公司使用的是

package com.google.common.cache;

来进行的缓存
我的怀疑是 1.有可能是cache的池的大小负载过了
2.可能是定时任务的锅 更新的时候把以前的缓存搞丢了

引用的maven依赖,使用的是guava缓存机制
 


    com.google.guava
    guava
    11.0.2

 

 

1.cache中的softValues()是什么意思

softValues()方法,这样map中的value值都包裹在一个SoftReference(软引用)对象中,可以在内存过低的时候被当作垃圾回收。

所以这个在我们的cache机制中没有进行添加使用

Guava Cache缓存机制有两个基本的接口:Cache和LoadingCache,LoadingCache接口继承自Cache接口。

Cache

Cache接口提供了键和值的映射,但是Cache接口中提供的一些方法比HashMap提供的更基本。使用maps或caches的传统做法是:我们提供一个key,如果缓存中存在key对应的value值,我们就将这个value值返回,否则的话,如果通过相应的key找到映射关系,就返回null 值,为了在缓存中设置value值,我们可能需要这样做:

put(key,value);

我们需要明确的在cache或map中关联key和value,Cache使用了传统的put方法设置value值,但是获取value的时候,Guava Cache有自己的调用风格,如下:

V value = cache.get(key, Callable value);

上面的方法会检索当前的value值,如果值不存在的话会从Callback实例中提取value值,通过key关联value,并返回相应的value值,它为我们提供了通过调用一个方法来替代下面风格的编程:

value = cache.get(key);
 
if(value == null){
 
    value =someService.retrieveValue();
 
    cache.put(key,value);
 
}

//也就是说没有得到get对应的value值,那么通过callback来进行添加相应的key和value
 

spring中bean的scope属性,有如下5种类型:

  1. singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例
  2. prototype表示每次获得bean都会生成一个新的对象
  3. request表示在一次http请求内有效(只适用于web应用)
  4. session表示在一个用户会话内有效(只适用于web应用)
  5. globalSession表示在全局会话内有效(只适用于web应用)

2. refresh和expire刷新机制

刷新机制:包括refresh和expire刷新机制

expireAfterAccess: 当缓存项在指定的时间段内没有被读或写就会被回收。

expireAfterWrite:当缓存项在指定的时间段内没有更新就会被回收。

refreshAfterWrite:当缓存项上一次更新操作之后的多久会被刷新。

   考虑到时效性,我们可以使用expireAfterWrite,使每次更新之后的指定时间让缓存失效,然后重新加载缓存。guava cache会严格限制只有1个加载操作,这样会很好地防止缓存失效的瞬间大量请求穿透到后端引起雪崩效应。
     然而,通过分析源码,guava cache在限制只有1个加载操作时进行加锁,其他请求必须阻塞等待这个加载操作完成;而且,在加载完成之后,其他请求的线程会逐一获得锁,去判断是否已被加载完成,每个线程必须轮流地走一个“”获得锁,获得值,释放锁“”的过程,这样性能会有一些损耗。这里由于我们计划本地缓存1秒,所以频繁的过期和加载,锁等待等过程会让性能有较大的损耗。

     因此我们考虑使用refreshAfterWrite。refreshAfterWrite的特点是,在refresh的过程中,严格限制只有1个重新加载操作,而其他查询先返回旧值,这样有效地可以减少等待和锁争用,所以refreshAfterWrite会比expireAfterWrite性能好。但是它也有一个缺点,因为到达指定时间后,它不能严格保证所有的查询都获取到新值。了解过guava cache的定时失效(或刷新)原来的同学都知道,guava cache并没使用额外的线程去做定时清理和加载的功能,而是依赖于查询请求。在查询的时候去比对上次更新的时间,如超过指定时间则进行加载或刷新。所以,如果使用refreshAfterWrite,在吞吐量很低的情况下,如很长一段时间内没有查询之后,发生的查询有可能会得到一个旧值(这个旧值可能来自于很长时间之前),这将会引发问题。
--------------------- 
作者:Shiftyman 
原文:https://blog.csdn.net/abc86319253/article/details/53020432 

//感觉讲得很好

你可能感兴趣的:(java后端)