
# 缓存优先
clientcontrol提供了一种名为缓存优先的功能。当使用缓存优先功能时，在执行目标业务代码时，优先会查询缓存，如果缓存存在则返回缓存结果，如果缓存不存在则执行目标业务代码。
当使用缓存优先时clientcontrol的处理逻辑如下：
- 读取缓存，判断是否是性能缓存。
  - 如果是性能缓存，直接将性能缓存当结果返回。
  
  - 如果不是性能缓存，执行原方法。
   

- 如果原方法执行成功，更新缓存，返回结果。 如果原方法执行失败，返回获取的缓存。
- 如果一开始没有获取到缓存，会直接将原方法执行失败的异常返回。
性能缓存是clientcontrol自带的一个概念，对应配置参数中的performance-ttl。例如一个缓存的有效时长是10s，那性能缓存可以配置为3s，代表一个逻辑概念，标识缓存的结果离更新缓存的时间更近，不会对实际的缓存产生影响。
具体使用方式如下：
1. [pom文件添加依赖](https://support.huaweicloud.com/devg-astropro/astropro_06_0079.html#astropro_06_0079__li1026515252452)。
2. 配置文件，参考下面配置样例。 
   ```
   devspore:
     client-control:
       caches:
         test:
           ttl: 60000  #此处配置的是缓存的有效时长
           performance-ttl: 30000  #此处配置的是一个性能缓存，时长一般低于ttl， 当缓存的时间小于性能缓存时，clientcontrol会直接把性能缓存作为方法返回值返回
           type: redis  此处配置的是 缓存类型， 支持 redis/caffine 指定具体缓存类型后，用户需要手动引入相关的依赖
           maximum-size: 60000
           redis-connection-factory-bean-name: redisConnectionFactory  # 当使用redis的时候，需要将redis的连接工厂的bean的名称配置在这里
       rules:
         fallbackTest: # 此处配置的是一个别名，用户可自定义，具体使用地方是在注解上
           time-limit:
             enable: false
           retry:
             enable: false
           fallback:
             # 默认开启
             enable: true
             # 慢调用时间（超过即为慢调用，单位s，默认60S）
             slow-call-duration-threshold: 30
             # 慢调用熔断比例（慢调用数量达到比例则熔断，默认100等于关闭状态）
             slow-call-rate-threshold: 100
             #失败百分比（触发断路器，默认50%）
             failure-rate-threshold: 50
             #滑动窗口类型（COUNT_BASED/TIME_BASED,数量/时间，默认时间）
             sliding-window-type: COUNT_BASED
             #滑动窗口大小(默认100，数量：次/时间：秒)
             sliding-window-size: 5
             #滑动窗口内最小请求数(默认100)   必须满足这个要求，才会触发断路器  不满足，不管失败率多少都不会触发
             minimum-number-of-calls: 5
             #进入半开所需时间(默认60s，单位ms)
             wait-duration-in-open-state: 10000
             #半开状态允许通过的请求数量，默认10个请求（失败比例达到设置的百分比，断路器继续打开，再次等待进入半开）注：不大于滑动窗口内最小请求数，相对较小的配置优先起作用，所以如果大于滑动窗口最小请求，起作用的就是滑动窗口最小请求数了
             permitted-number-of-calls-in-half-open-state: 5
   ```
   
   
3. 目标方法上添加@ClientControl注解，且policy属性设置为CacheOrder.CACHEFIRST，rule属性选择配置文件中自己定义的rules名称（本示例中使用fallbackTest），cacheManagerName属性选择配置文件中自己定义的caches的名称（本示例使用test）。 
   ```
   @ClientControl(rule = "fallbackTest", policy = CacheOrder.CACHEFIRST, cacheManagerName = "test")
   public String testClientControlJiangji(Integer id) {
   int i = 1 / id;
   return new User(id, "vn", 12).toString();
   }
   ```
   
   
 
