简单总结下文内容:
- expireAfterAccess表示多久没有访问(读或写)就失效
- expireAfterWrite表示多久没有更新就失效
expireAfterAccess和expireAfterWrite注意点如下:使用场景:
业务非常注重缓存的时效性缺点:
性能较差,缓存过期后,所有线程都要等待和锁争用,尽管guava可以保证只有一个线程load缓存(很好地防止缓存失效的瞬间大量请求穿透到后端引起雪崩效应),但是其他线程也要等待和锁争用 - refreshAfterWrite表示继上次更新后多久刷新
优点与缺点:
优点是refresh性能要比load好很多,guava保证只有一个线程refresh缓存,缺点是其他缓存返回旧值,这个旧值可能是很多之前的旧值(原因refresh动作不是自动轮询执行的,而是在get请求的时候才会检查是否需要refresh、如需要在refresh,其他线程直接返回旧值可能是很久之前的,有效减少等待和锁的争用,性能较好) - 另外补充一下,load时value不能是null,否则get时会抛出异常,如果value值可能是null,则要用Optional包一下,避免通过try-catch处理null
通过上面可以看到expireAfterWrite和refreshAfterWrite都有优缺点,只配置一个属性不是性能差、就是获取到很久之前的旧值引发业务问题,因此2个属性可以搭配使用,例如expireAfterWrite=2s、refreshAfterWrite=1s,比如说控制缓存每1s进行refresh,如果超过2s没有访问,那么则让缓存失效,下次访问时不会得到旧值,而是必须得待新值加载