# 緩存插件
`ESD` 已默認啟用本插件。
## 插件使用
緩存可以使用注解的形式,在需要加緩存的函數中添加相關注釋。
>[danger] **添加注解的函數不能為`private`。**
引用
~~~
use ESD\Plugins\Cache\Annotation\Cacheable;
~~~
## Cacheable 方法
>[info]如果緩存不存在就創建,如果存在就直接返回。
參數說明
> ### $key = "";
代表需要刪除的命名空間下唯一的緩存`key`。 使用`php`語法,`$p[0]` 獲取對應參數,可以增加前綴,其值最終將作為表達式在 `eval` 中執行。
~~~
/**
* @Cacheable(key="$p[0]", namespace="user")
* @param $id
* @return array
*/
~~~
~~~
/**
* @Cacheable(key="'user_'.$p[0]", namespace="user")
* @param $id
* @return array
*/
~~~
~~~
/**
* @Cacheable(key="'user_'.$p[0]->user", namespace="user")
* @param $id
* @return array
*/
~~~
> ### $time = 0;
緩存時間 0 代表使用默認時間,-1 代表無限時間,對有 `namespace` 的無效,`namespace`底層使用`hset`存儲,無法單獨設置時間。同時如果使用默認時間底層會對緩存超時設置一個`20%`以內的浮動。如果不需要此特性請設置該參數或覆蓋默認設置。
~~~
/**
* @Cacheable(key="$p[0]", time="3000")
* @param $id
* @return array
*/
~~~
> ### namespace= ""
對緩存進行分組,分組的數據底層存放`hset`,所以不能設置過期時間。后期刪除可以針對`namespace`批量刪除。
~~~
/**
* @Cacheable(key="$p[0]", namespace="user")
* @param $id
* @return array
*/
~~~
> ### $condition = "";
有的時候我們可能并不希望緩存一個方法所有的返回結果。
通過 `condition `屬性可以實現這一功能。`condition`屬性默認為空,表示將緩存所有的調用情形。
其值是通過PHP表達式來指定的,當為true時表示進行緩存處理;
當為false時表示不進行緩存處理,即每次調用該方法時該方法都會執行一次。
~~~
/**
* @Cacheable(key="'cache_test'.$p[0]", namespace="test", condition="$p[0] >= 5")
*/
~~~
使用例子
~~~
/**
* get操作創建緩存
* @Cacheable(key="'cache_test'.$p[0]", namespace="test", condition="$p[0] >= 5")
* @param $id
* @return array
*/
protected function cacheTest($id){
$res = $this->mysql->query("SHOW GLOBAL STATUS LIKE '%connections%'");
$this->log->debug('cacheTest db', $res);
return $res;
}
~~~
## CacheEvict
>[info]無論緩存是否存在,始終清除緩存
引用
~~~
use GoSwoole\Plugins\Cache\Annotation\CacheEvict;
~~~
除了Cacheable方法之外的參數還有以下參數
> ### $allEntries = false;
標記是否刪除命名空間下所有緩存,默認為`false`
> ### $beforeInvocation = false;
在調用方法之前清除緩存中的指定元素,默認為`false`
默認設置下,清除操作是在對應方法成功執行之后觸發的,如果方法因為拋出異常而未能成功返回時也不會觸發清除操作。使用`beforeInvocation`可以改變觸發清除操作的時間,當我們指定該屬性值為`true`時,會在調用該方法之前清除緩存中的指定元素。
使用例子
~~~
/**
* update刪除緩存
* @CacheEvict(key="'cache_test'.$p[0]",namespace="test", allEntries="true", beforeInvocation="true")
* @param $id
* @return array
*/
public function updateTest($id){
//do something
return $res;
}
~~~
### CachePut
>[info]不檢查緩存是否存在,始終生成緩存
引用
~~~
use GoSwoole\Plugins\Cache\Annotation\CachePut;
~~~
參數與 Cacheable 一致。
對于使用 `@Cacheable` 標注的方法,在每次執行前都會檢查 Cache 中是否存在相同key的緩存元素,如果存在就不再執行該方法,而是直接從緩存中獲取結果進行返回,否則才會執行并將返回結果存入指定的緩存中。
`@CachePut` 也可以聲明一個方法支持緩存功能。與 `@Cacheable `不同的是使用`@CachePut` 標注的方法在執行前`不會去檢查`緩存中是否存在之前執行過的結果,
而是`每次都會`執行該方法,并將執行結果以鍵值對的形式存入指定的緩存中。
## 配置項
無需配置即可直接使用,如果需要覆蓋默認配置,需要將被覆蓋的部分參數增加到 `application.yml`文件中。下面依次說明相關配置,
> 如無特別說明,以下列出的均為默認值,不改配置無需修改配置文件。
~~~
cache:
timeout: 1800 (緩存超時時間)
db: default (使用的redis連接標識)
cacheStorageClass: ESD\Plugins\Cache\RedisCacheStorage(使用的緩存驅動)
lock_timeout: 0 (是否開啟緩存讀鎖等待。此為高級功能下面詳細說明)
lock_wait: 500(讀取鎖等待重試間隔)
lock_alive: 20000(鎖存活時間)
~~~
## lock_timeout 配置
如果設置為0則不啟用讀寫鎖,開啟后寫入緩存時會進行加鎖,避免高并發緩存穿透。
高并發建議開啟該設置,并且調高 redis 連接池以及 redis 的連接數。
如果每秒并發2000,超時設置為3秒,那么會有2000個連接等待。
如果秒級 set 建議設置 3000
如果幾百毫秒 set 建議設置 1000
如果不到100毫秒 set 建議設置 500
注意只有 Cacheable 方法支持該功能
>[danger] 如果鎖超時,同樣會直接訪問數據庫獲取數據。
## lockWait 配置
讀取鎖等待重試時長,單位(毫秒)。
每隔 lockWait 重試,如果緩存寫入需要秒級,建議調整 lockWait 為 500 毫秒以上
如果緩存寫入需要 幾百毫秒級,建議使用默認 100 毫秒
如果緩存寫入需要 一百毫秒以內,建議設置 50 毫秒
注意: 此值設置的太低會嚴重增加 redis get 負載, 如果每秒并發 2000,超時設置3秒,默認鎖等待100 毫秒,那么最差會有6萬get操作
注意:等待時長不要超過lockTimeout,否則會浪費協程資源。
## lockAlive 配置
死鎖過期時間 單位(毫秒)
注意:lockAlive 一定要大于lock_timeout 時間,否則如果鎖釋放了還沒有寫入緩存同樣會造成緩存穿透。
注意:配置在 application.yml 中,大寫字符需要以下劃線的形式覆蓋默認配置。
- 前言
- 捐贈ESD項目
- 使用篇-通用
- 環境
- 安裝
- 規范
- 壓力測試
- 配置
- 如何設置YML配置
- server配置
- 端口配置
- 項目結構
- 事件派發
- 日志
- 注解
- DI容器
- 自定義進程
- 并發及協程池
- Console插件
- Scheduled插件
- Redis插件
- AOP插件
- Saber插件
- Mysql插件
- mysql事務
- Actuator插件
- Whoops插件
- Cache插件
- PHPUnit插件
- Security插件
- Session插件
- EasyRoute插件
- http路由
- ProcessRpc插件
- AutoReload插件
- AnnotationsScan插件
- Tracing-plugin插件
- MQTT插件
- Pack插件
- AMQP插件
- Validate插件
- Uid插件
- Topic插件
- Blade插件
- CsvReader插件
- hashed-wheel-timer-plugin插件
- 使用篇-HTTP
- 路由
- 靜態文件
- 路由定義
- 修飾方法
- 路由分組
- 資源路由
- 端口作用域
- 異常處理
- 跨域請求
- 路由緩存
- 控制器
- 控制器初始化
- 前置操作
- 跳轉和重定向
- 異常處理
- 請求
- 請求對象
- 請求信息
- request消息
- response消息
- stream消息
- url接口
- 驗證器
- 內置驗證器
- 內置過濾器
- 使用篇-WS
- 如何使用
- 路由
- 使用篇-TCP
- 插件篇-PluginSystem
- 微服務篇-ESDCloud
- CircuitBreaker插件
- SaberCloud插件
- 分布式鏈路追蹤系統
- Consul插件