<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          阿里這款多級緩存框架一定要掌握,非常不錯!

          共 16826字,需瀏覽 34分鐘

           ·

          2023-08-19 13:12

          點擊關(guān)注公眾號,Java干貨 及時送達 ??


          在實際應用中,并不是單一的使用本地緩存或者redis,更多是組合使用來滿足不同的業(yè)務場景,于是如何優(yōu)雅的組合本地緩存和遠程緩存就成了我們要研究的問題,而這一點,阿里開源的 jetcache 組件幫我們實現(xiàn)了

          犬小哈教程網(wǎng) www.quanxiaoha.com

          1. jetcache簡介

          jetcache是阿里開源的基于java開發(fā)的緩存框架,支持多種緩存類型:本地緩存、分布式緩存、多級緩存。能夠滿足不同業(yè)務場景的緩存需求。

          jetcache具有上手簡單、性能高效、拓展性強的特點。支持緩存預熱 、緩存key前綴等功能。結(jié)合spring-cache使用,可以實現(xiàn)十分優(yōu)雅的緩存類型切換

          官網(wǎng)地址:https://github.com/alibaba/jetcache

          官方文檔:https://github.com/alibaba/jetcache/tree/master/docs/CN

          基于 Spring Boot + MyBatis Plus + Vue 3.2 + Vite + Element Plus 實現(xiàn)的前后端分離博客,包含后臺管理系統(tǒng),支持文章、分類、標簽管理、儀表盤等功能。

          • GitHub 地址:https://github.com/weiwosuoai/WeBlog
          • Gitee 地址:https://gitee.com/AllenJiang/WeBlog

          2. jetcache使用

          1、引入依賴,這里我們使用sringboot項目框架,同時使用redis作為遠程緩存。于是我們引入jetcache-starter-redis依賴,這里我的springboot版本為2.6.13

          如果是非springboot項目可以參考官網(wǎng)說明配置

          3880a23592c7acdd81eb829db27347f2.webp

                
                <dependency>
                      <groupId>com.alicp.jetcache</groupId>
                      <artifactId>jetcache-starter-redis</artifactId>
                      <version>2.7.0</version>
          </dependency>

          <!--        jetcache2.7.x版本需要額外添加該依賴-->
          <dependency>
                      <groupId>redis.clients</groupId>
                      <artifactId>jedis</artifactId>
                      <version>4.3.1</version>
          </dependency>

          對應的版本說明如下:https://github.com/alibaba/jetcache/blob/master/docs/CN/Compatibility.md

          ab4aa0bd72d10e1ae4321066600b9e96.webp

          2、修改配置文件,配置redis地址和線程數(shù)

                
                jetcache:
            ## 統(tǒng)計間隔,0表示不統(tǒng)計,開啟后定期在控制臺輸出緩存信息
            statIntervalMinutes: 15
            ## 是否把cacheName作為遠程緩存key前綴
            areaInCacheName: false
            ## 本地緩存配置
            local:
              default: ## default表示全部生效,也可以指定某個cacheName
                ## 本地緩存類型,其他可選:caffeine/linkedhashmap
                type: linkedhashmap
                keyConvertor: fastjson
            ## 遠程緩存配置
            remote:
              default: ## default表示全部生效,也可以指定某個cacheName
                type: redis
                ## key轉(zhuǎn)換器方式n
                keyConvertor: fastjson
                broadcastChannel: projectA
                ## redis序列化方式
                valueEncoder: java
                valueDecoder: java
                ## redis線程池
                poolConfig:
                  minIdle: 5
                  maxIdle: 20
                  maxTotal: 50
                ## redis地址與端口
                host: 127.0.0.1
                port: 6379

          更詳細的參數(shù)配置可參考官網(wǎng)說明:

          9fea7aadfed7ebf3bb9daebee272d7e6.webp

          3、啟動類添加注解@EnableCreateCacheAnnotation,開啟緩存,添加@EnableMethodCache(basePackages = "com.example.jetcachedemo")注解,配置緩存方法掃描路徑

          4、使用緩存可以通過三種方式:

          • 方式一(推薦)AOP模式:通過@Cached,@CacheUpdate,@CacheInvalidate注解
                
                @RestController
          @RequestMapping("user")
          public class UserController {

              @GetMapping("getRemote")
              @Cached(name="userCache:", key = "#id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.REMOTE)
              public User getRemote(Long id){
                  // 直接新建用戶,模擬從數(shù)據(jù)庫獲取數(shù)據(jù)
                  User user = new User();
                  user.setId(id);
                  user.setName("用戶remote"+id);
                  user.setAge(23);
                  user.setSex(1);
                  System.out.println("第一次獲取數(shù)據(jù),未走緩存:"+id);
                  return user;
              }

              @GetMapping("getLocal")
              @Cached(name="userCache:", key = "#id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.LOCAL)
              public User getLocal(Long id){
                  // 直接新建用戶,模擬從數(shù)據(jù)庫獲取數(shù)據(jù)
                  User user = new User();
                  user.setId(id);
                  user.setName("用戶local"+id);
                  user.setAge(23);
                  user.setSex(1);
                  System.out.println("第一次獲取數(shù)據(jù),未走緩存:"+id);
                  return user;
              }

              @GetMapping("getBoth")
              @Cached(name="userCache:", key = "#id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.BOTH)
              public User getBoth(Long id){
                  // 直接新建用戶,模擬從數(shù)據(jù)庫獲取數(shù)據(jù)
                  User user = new User();
                  user.setId(id);
                  user.setName("用戶both"+id);
                  user.setAge(23);
                  user.setSex(1);
                  System.out.println("第一次獲取數(shù)據(jù),未走緩存:"+id);
                  return user;
              }

              @PostMapping("updateUser")
              @CacheUpdate(name = "userCache:", key = "#user.id", value = "#user")
              public Boolean updateUser(@RequestBody User user){
                  // TODO 更新數(shù)據(jù)庫
                  return true;
              }

              @PostMapping("deleteUser")
              @CacheInvalidate(name = "userCache:", key = "#id")
              public Boolean deleteUser(Long id){
                  // TODO 從數(shù)據(jù)庫刪除
                  return true;
              }

          }

          這里要注意實體類User一定要實現(xiàn)序列化,即聲明Serializable

                
                @Data
          public class User implements Serializable {

              private Long id;
              private String name;
              private Integer age;
              private Integer sex;
          }
          • 方式二 API模式:通過@CreateCache,注:在jetcache 2.7 版本CreateCache注解已廢棄,不推薦使用
                
                @RestController
          @RequestMapping("user2")
          public class User2Controller {

              @CreateCache(name= "userCache:", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.BOTH)
              private Cache<Long, Object> userCache;

              @GetMapping("get")
              public User get(Long id){
                  if(userCache.get(id) != null){
                      return (User) userCache.get(id);
                  }
                  User user = new User();
                  user.setId(id);
                  user.setName("用戶both"+id);
                  user.setAge(23);
                  user.setSex(1);
                  userCache.put(id, user);
                  System.out.println("第一次獲取數(shù)據(jù),未走緩存:"+id);
                  return user;
              }

              @PostMapping("updateUser")
              public Boolean updateUser(@RequestBody User user){
                  // TODO 更新數(shù)據(jù)庫
                  userCache.put(user.getId(), user);
                  return true;
              }

              @PostMapping("deleteUser")
              public Boolean deleteUser(Long id){
                  // TODO 從數(shù)據(jù)庫刪除
                  userCache.remove(id);
                  return true;
              }

          }
          • 方式三 高級API模式:通過CacheManager,2.7 版本才可使用

          (1)添加依賴

                
                <dependency>
                      <groupId>com.alibaba</groupId>
                      <artifactId>fastjson</artifactId>
                      <version>2.0.25</version>
          </dependency>

          (2)書寫配置類

                
                @Configuration
          public class JetcacheConfig {

              @Autowired
              private CacheManager cacheManager;
              private Cache<Long, Object> userCache;

              @PostConstruct
              public void init(){
                  QuickConfig qc = QuickConfig.newBuilder("userCache:")
                          .expire(Duration.ofSeconds(3600))
                          .cacheType(CacheType.BOTH)
                          // 本地緩存更新后,將在所有的節(jié)點中刪除緩存,以保持強一致性
                          .syncLocal(false)
                          .build();
                  userCache = cacheManager.getOrCreateCache(qc);
              }

              @Bean
              public Cache<Long, Object> getUserCache(){
                  return userCache;
              }
          }

          (3)調(diào)用代碼

                
                @RestController
          @RequestMapping("user3")
          public class User3Controller {

              @Autowired
              JetcacheConfig jetcacheConfig;
              @Autowired
              private Cache<Long, Object> userCache;

              @GetMapping("get")
              public User get(Long id){
                  if(userCache.get(id) != null){
                      return (User) userCache.get(id);
                  }
                  User user = new User();
                  user.setId(id);
                  user.setName("用戶both"+id);
                  user.setAge(23);
                  user.setSex(1);
                  userCache.put(id, user);
                  System.out.println("第一次獲取數(shù)據(jù),未走緩存:"+id);
                  return user;
              }

              @PostMapping("updateUser")
              public Boolean updateUser(@RequestBody User user){
                  // TODO 更新數(shù)據(jù)庫
                  userCache.put(user.getId(), user);
                  return true;
              }

              @PostMapping("deleteUser")
              public Boolean deleteUser(Long id){
                  // TODO 從數(shù)據(jù)庫刪除
                  userCache.remove(id);
                  return true;
              }

          }

          多級緩存的形式,會先從本地緩存獲取數(shù)據(jù),本地獲取不到會從遠程緩存獲取;

          基于 Spring Boot + MyBatis Plus + Vue 3.2 + Vite + Element Plus 實現(xiàn)的前后端分離博客,包含后臺管理系統(tǒng),支持文章、分類、標簽管理、儀表盤等功能。

          • GitHub 地址:https://github.com/weiwosuoai/WeBlog
          • Gitee 地址:https://gitee.com/AllenJiang/WeBlog

          5、啟動redis,啟動演示項目

          注意,如果啟動出現(xiàn)NoClassDefFoundError: redis/clients/util/PoolNoClassDefFoundError: redis/clients/jedis/UnifiedJedis報錯,說明springboot與jetcache版本不一致,對應關(guān)系可參考上述第一步中的說明 同時如果使用的是jetcache2.7.x版本,因為該版本中有jedis包的依賴,需要額外添加如下依賴,或者將jetcache版本將至2.6.5以下

                
                <dependency>
                      <groupId>redis.clients</groupId>
                      <artifactId>jedis</artifactId>
                      <version>4.3.1</version>
          </dependency>

          3. 測試

          3.1 方式一測試

          1、訪問localhost:8088/user/getRemote?id=1

          1ca710fc76769aac64af3a352a2e2571.webp

          因為配置的是遠程緩存,在redis中也能看到對應的key

          cdec7300e33c37e4f18e1015c518364c.webp

          2、訪問localhost:8088/user/getLocal?id=1,這個方法是從本地緩存獲取的,現(xiàn)在只有遠程緩存上有數(shù)據(jù),我們調(diào)用發(fā)現(xiàn)緩存數(shù)據(jù)還是拿到了,這說明當我們在配置文件中配置了本地緩存和遠程緩存后,方式一中本地緩存和遠程緩存會自動相互調(diào)用

          比如本地緩存有這個key,redis中沒有,通過遠程緩存方式訪問時,會先從redis獲取,如果沒有會自動獲取本地緩存,但是數(shù)據(jù)還是存儲在本地緩存,并不會同步到redis上,這樣更加靈活的實現(xiàn)了多級緩存架構(gòu)

          4dd828d9da336acc74176318d07c75cc.webp

          3.2 方式二測試

          1、再測試下CreateCache的形式:localhost:8088/user2/get?id=4

          19b9b62333af1b4bb22eaf7180c1e673.webp

          正常獲取了,并且redis中也有了對應的值

          c9bb85d980e60a28e42aa0e3c9e1e164.webp 而當我們把緩存方式更改為LOCAL后,再訪問localhost:8088/user2/get?id=5

                
                @CreateCache(name= "userCache:", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.LOCAL)

          會發(fā)現(xiàn)redis中就沒有對應緩存了,只在本地緩存存在,說明我們指定本地緩存的形式成功了

          1656817e2a688dfcb5ed2da1371ef513.webp

          3.3 方式三測試

          1、調(diào)用localhost:8088/user3/get?id=11

          e43f737fe89419917cbebc6001bc4589.webp

          redis中緩存設置成功!

          7081dfafecd276da0f9d24d8dd73f202.webp

          4. 常見報錯

          1、 ClassNotFoundException: com.alibaba.fastjson.JSON 解決:添加依賴

                
                <dependency>
                      <groupId>com.alibaba</groupId>
                      <artifactId>fastjson</artifactId>
                      <version>2.0.25</version>
          </dependency>

          2、NoClassDefFoundError: redis/clients/jedis/UnifiedJedis 解決:添加依賴

                
                <dependency>
                      <groupId>redis.clients</groupId>
                      <artifactId>jedis</artifactId>
                      <version>4.3.1</version>
          </dependency>

          或者將jetcache版本降低至2.6.5以下

          來源:https://juejin.cn/post/7247151913437937701

                
                  
                    
                      

          1. 前后端分離,開源的 Spring Boot + Vue 3.2 的博客,泰褲辣!

          2. 如何畫出一張優(yōu)秀的架構(gòu)圖(老鳥必備)

          3. 21.5K Star!最佳開源堡壘機,開箱即用!

          4. 字節(jié)二面:10Wqps會員系統(tǒng),如何設計?

          deab064da05613ddabeacd796c20f23b.webp

                        

          最近面試BAT,整理一份面試資料 Java面試BATJ通關(guān)手冊 ,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點“ 在看 ”,關(guān)注公眾號并回復  Java  領取,更多內(nèi)容陸續(xù)奉上。

                        

          PS:因公眾號平臺更改了推送規(guī)則,如果不想錯過內(nèi)容,記得讀完點一下 在看 ,加個 星標 ,這樣每次新文章推送才會第一時間出現(xiàn)在你的訂閱列表里。

          “在看”支持小哈呀,謝謝啦

          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲青青视频 | 日韩一区在线视频 | 干干网| 豆花视频一区 | 久久久91人妻无码精品蜜桃ID |