<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>

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

          共 16149字,需瀏覽 33分鐘

           ·

          2024-07-23 19:00

          來源:juejin.cn/user/4068629263428382/posts

          • 1. jetcache簡介
          • 2. jetcache使用
          • 3. 測試
          • 4. 常見報錯

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

          1. jetcache簡介

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

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

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

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

          2. jetcache使用

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

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

          <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>

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

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

          jetcache:
            # 統(tǒng)計間隔,0表示不統(tǒng)計,開啟后定期在控制臺輸出緩存信息
            statIntervalMinutes: 15
            # 是否把cacheName作為遠(yuǎn)程緩存key前綴
            areaInCacheName: false
            # 本地緩存配置
            local:
              default: # default表示全部生效,也可以指定某個cacheName
                # 本地緩存類型,其他可選:caffeine/linkedhashmap
                type: linkedhashmap
                keyConvertor: fastjson
            # 遠(yuǎn)程緩存配置
            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

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

          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;
              }

          }

          這里要注意實(shí)體類User一定要實(shí)現(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é)點(diǎn)中刪除緩存,以保持強(qiáng)一致性
                          .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ù),本地獲取不到會從遠(yuǎn)程緩存獲取;關(guān)注工眾號:碼猿技術(shù)專欄,回復(fù)關(guān)鍵詞:1111 獲取阿里內(nèi)部Java性能調(diào)優(yōu)手冊!

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

          注意,如果啟動出現(xiàn)NoClassDefFoundError: redis/clients/util/PoolNoClassDefFoundError: redis/clients/jedis/UnifiedJedis報錯,說明springboot與jetcache版本不一致,對應(yīng)關(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

          因為配置的是遠(yuǎn)程緩存,在redis中也能看到對應(yīng)的key

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

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

          3.2 方式二測試

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

          正常獲取了,并且redis中也有了對應(yīng)的值

          而當(dāng)我們把緩存方式更改為LOCAL后,再訪問localhost:8088/user2/get?id=5

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

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

          3.3 方式三測試

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

          redis中緩存設(shè)置成功!

          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以下

          瀏覽 157
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  天天噜天天操 | 五月天婷婷基地 | 麻豆传媒视频免费观看网站网址 | 操必网 | 黄色在线视频免费观看 |