日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

阿里开源 JetCache 缓存框架介绍使用

發布時間:2023/12/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 阿里开源 JetCache 缓存框架介绍使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、JetCache

JetCache是一個基于Java的緩存系統封裝,提供統一的API和注解來簡化緩存的使用。 JetCache提供了比SpringCache更加強大的注解,可以原生的支持TTL、兩級緩存、分布式自動刷新,還提供了Cache接口用于手工緩存操作。 當前有四個實現,RedisCache、TairCache(此部分未在github開源)、CaffeineCache(in memory)和一個簡易的LinkedHashMapCache(in memory),要添加新的實現也是非常簡單的。

全部特性:

  • 通過統一的API訪問Cache系統
  • 通過注解實現聲明式的方法緩存,支持TTL和兩級緩存
  • 通過注解創建并配置Cache實例
  • 針對所有Cache實例和方法緩存的自動統計
  • Key的生成策略和Value的序列化策略是可以配置的
  • 分布式緩存自動刷新,分布式鎖 (2.2+)
  • 異步Cache API (2.2+,使用Redis的lettuce客戶端時)
  • Spring Boot支持

github地址: https://github.com/alibaba/jetcache

注意:

JetCache需要JDK1.8、Spring Framework4.0.8以上版本。Spring Boot為可選,需要1.1.9以上版本。如果不使用注解(僅使用jetcache-core),Spring Framework也是可選的,此時使用方式與Guava/Caffeine cache類似。

二、SpringBoot 引入

  • pom
  • <!-- https://mvnrepository.com/artifact/com.alicp.jetcache/jetcache-starter-redis-lettuce --><dependency><groupId>com.alicp.jetcache</groupId><artifactId>jetcache-starter-redis-lettuce</artifactId><version>2.6.0.M1</version></dependency><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId></dependency><!-- 添加對redis的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- 添加對連接池的支持 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>
  • application.yml
  • jetcache:statIntervalMinutes: 1 #統計間隔areaInCacheName: falselocal:default: #默認areatype: caffeinekeyConvertor: fastjsonremote:default:type: redis.lettuce #使用lettucekeyConvertor: fastjsonvalueEncoder: javavalueDecoder: javapoolConfig:minIdle: 1maxIdle: 50maxTotal: 1000maxWait: 1000 # uri: ['redis://password@192.168.0.1:6379/0','redis://password@192.168.0.2:6379/0','redis://password@192.168.0.3:6379/0']uri:- redis://password@192.168.0.1:6379/0 #redis://密碼@IP:端口/庫- redis://password@192.168.0.2:6379/0- redis://password@192.168.0.3:6379/0readFrom: masterPreferred #master優先
  • 啟動類開啟緩存
  • @SpringBootApplication @EnableCreateCacheAnnotation @EnableMethodCache(basePackages = { "com.bxc.jetcache.jetcachedemo.service" }) public class JetcacheDemoApplication {public static void main(String[] args) {SpringApplication.run(JetcacheDemoApplication.class, args);}}

    三、方法緩存

    1. @Cached

    使用@Cached方法可以為一個方法添加上緩存。JetCache通過Spring AOP生成代理,來支持緩存功能。注解可以加在接口方法上也可以加在類方法上,但需要保證是個Spring bean。

    @Cached(name = "bxcCache:", cacheType = CacheType.BOTH, key = "#id", expire = 30, timeUnit = TimeUnit.MINUTES) public String getCache(String id) {System.out.println("哈哈哈哈");return "abc"; }@CacheUpdate(name = "bxcCache:", key = "#id", value = "#result") public String updateCache(String id) {return "update"; }@CacheInvalidate(name = "bxcCache:", key = "#id") public String deleteCache(String id){return "delete"; }

    上面代碼中可以看出,我們可以使用SpEL(Spring Expression Language)來設置key和Value。name屬性不是必須的,但是起個名字是個好習慣,展示統計數據的使用,會使用這個名字。如果同一個area兩個@CreateCache的name配置一樣,它們生成的Cache將指向同一個實例。這里面需要注意的是,java代碼的編輯級別必須是1.8。

    其中CacheType

    CacheType.REMOTE 遠程緩存,如:redis
    CacheType.LOCAL本地緩存,如:linkedhashmap、caffeine
    CacheType.BOTH 本地+遠程緩存,二級緩存

    @CacheUpdate和@CacheInvalidate的name和area屬性必須和@Cached相同,name屬性還會用做cache的key前綴。

    @Cached注解和@CreateCache的屬性非常類似,但是多幾個:

    屬性默認值說明
    area“default”如果在配置中配置了多個緩存area,在這里指定使用哪個area
    name未定義指定緩存的唯一名稱,不是必須的,如果沒有指定,會使用類名+方法名。name會被用于遠程緩存的key前綴。另外在統計中,一個簡短有意義的名字會提高可讀性。
    key未定義使用SpEL指定key,如果沒有指定會根據所有參數自動生成。
    expire未定義超時時間。如果注解上沒有定義,會使用全局配置,如果此時全局配置也沒有定義,則為無窮大
    timeUnitTimeUnit.SECONDS指定expire的單位
    cacheTypeCacheType.REMOTE緩存的類型,包括CacheType.REMOTE、CacheType.LOCAL、CacheType.BOTH。如果定義為BOTH,會使用LOCAL和REMOTE組合成兩級緩存
    localLimit未定義如果cacheType為LOCAL或BOTH,這個參數指定本地緩存的最大元素數量,以控制內存占用。如果注解上沒有定義,會使用全局配置,如果此時全局配置也沒有定義,則為100
    localExpire未定義僅當cacheType為BOTH時適用,為內存中的Cache指定一個不一樣的超時時間,通常應該小于expire
    serialPolicy未定義指定遠程緩存的序列化方式。可選值為SerialPolicy.JAVA和SerialPolicy.KRYO。如果注解上沒有定義,會使用全局配置,如果此時全局配置也沒有定義,則為SerialPolicy.JAVA
    keyConvertor未定義指定KEY的轉換方式,用于將復雜的KEY類型轉換為緩存實現可以接受的類型,當前支持KeyConvertor.FASTJSON和KeyConvertor.NONE。NONE表示不轉換,FASTJSON可以將復雜對象KEY轉換成String。如果注解上沒有定義,會使用全局配置。
    enabledtrue是否激活緩存。例如某個dao方法上加緩存注解,由于某些調用場景下不能有緩存,所以可以設置enabled為false,正常調用不會使用緩存,在需要的地方可使用CacheContext.enableCache在回調中激活緩存,緩存激活的標記在ThreadLocal上,該標記被設置后,所有enable=false的緩存都被激活
    cacheNullValuefalse當方法返回值為null的時候是否要緩存
    condition未定義使用SpEL指定條件,如果表達式返回true的時候才去緩存中查詢
    postCondition未定義使用SpEL指定條件,如果表達式返回true的時候才更新緩存,該評估在方法執行后進行,因此可以訪問到#result

    2. @CacheRefresh 自動刷新

    @CacheRefresh 相當于開始一個定時任務,定時刷新值到緩存中。

    @Cached(name = "bxcCache:", cacheType = CacheType.BOTH, key = "#id", expire = 30, timeUnit = TimeUnit.MINUTES) @CacheRefresh(refresh = 2, stopRefreshAfterLastAccess = 10, timeUnit = TimeUnit.SECONDS) public String getCache(String id) {System.out.println("哈哈哈哈");return "abc"; }

    refresh 刷新時間周期
    stopRefreshAfterLastAccess 停止刷新周期
    timeUnit 時間單位

    運行效果:

    @CacheRefresh注解說明:

    屬性默認值說明
    refresh未定義刷新間隔
    timeUnitTimeUnit.SECONDS時間單位
    stopRefreshAfterLastAccess未定義指定該key多長時間沒有訪問就停止刷新,如果不指定會一直刷新
    refreshLockTimeout60秒類型為BOTH/REMOTE的緩存刷新時,同時只會有一臺服務器在刷新,這臺服務器會在遠程緩存放置一個分布式鎖,此配置指定該鎖的超時時間

    3. @CachePenetrationProtect 同步加載數據

    當緩存訪問未命中的情況下,對并發進行的加載行為進行保護。 當前版本實現的是單JVM內的保護,即同一個JVM中同一個key只有一個線程去加載,其它線程等待結果。

    @Cached(name = "bxcCache:", cacheType = CacheType.BOTH, key = "#id", expire = 30, timeUnit = TimeUnit.MINUTES) @CachePenetrationProtect public String getCache(String id) {System.out.println("哈哈哈哈");return "abc"; }

    參數解析:

    四、緩存API

    使用@CreateCache注解去創建一個Cache實例

    @CreateCache(expire = 100, cacheType = CacheType.BOTH, localLimit = 50) private Cache<Long, UserDO> userCache;

    expire 超時時間
    cacheType 緩存類型
    localLimit 限制緩存數量

    //寫入緩存 cache.put("abc", "aaa"); //讀取緩存 System.out.println("1 > " + cache.get("abc"));System.out.println("2 > "+ cache.computeIfAbsent("abc1", res -> {return "111"; }));System.out.println("3 > " + cache.computeIfAbsent("abc2", res -> {return "222"; }, false, 10, TimeUnit.SECONDS));

    五、異步API

    從JetCache2.2版本開始,所有的大寫API返回的CacheResult都支持異步。當底層的緩存實現支持異步的時候,大寫API返回的結果都是異步的。當前支持異步的實現只有jetcache的redis-luttece實現,其他的緩存實現(內存中的、Tair、Jedis等),所有的異步接口都會同步堵塞,這樣API仍然是兼容的。

    CacheGetResult<UserDO> r = cache.GET(userId);

    這一行代碼執行完以后,緩存操作可能還沒有完成,如果此時調用r.isSuccess()或者r.getValue()或者r.getMessage()將會堵塞直到緩存操作完成。如果不想被堵塞,并且需要在緩存操作完成以后執行后續操作,可以這樣做:

    CompletionStage<ResultData> future = r.future(); future.thenRun(() -> {if(r.isSuccess()){System.out.println(r.getValue());} });

    以上代碼將會在緩存操作異步完成后,在完成異步操作的線程中調用thenRun中指定的回調。CompletionStage是Java8新增的功能,如果對此不太熟悉可以先查閱相關的文檔。需要注意的是,既然已經選擇了異步的開發方式,在回調中不能調用堵塞方法,以免堵塞其他的線程(回調方法很可能是在event loop線程中執行的)。

    部分小寫的api不需要任何修改,就可以直接享受到異步開發的好處。比如put和removeAll方法,由于它們沒有返回值,所以此時就直接優化成異步調用,能夠減少RT;而get方法由于需要取返回值,所以仍然會堵塞。

    六、分布式鎖

    boolean hasRun = cache.tryLockAndRun("liuxw3", 100, TimeUnit.SECONDS, () -> {System.out.println("我獲取到鎖了"); });

    總結

    以上是生活随笔為你收集整理的阿里开源 JetCache 缓存框架介绍使用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。