1. 程式人生 > 其它 >HM-SpringCloud微服務系列11.3.4【實現多級快取(3)】

HM-SpringCloud微服務系列11.3.4【實現多級快取(3)】

5. Redis快取預熱

5.1 新增redis快取的需求

5.2 冷啟動與快取預熱

Redis快取會面臨冷啟動問題:

冷啟動:服務剛剛啟動時,Redis中並沒有快取,如果所有商品資料都在第一次查詢時新增快取,可能會給資料庫帶來較大壓力。

快取預熱:在實際開發中,我們可以利用大資料統計使用者訪問的熱點資料,在專案啟動時將這些熱點資料提前查詢並儲存到Redis中。

我們資料量較少,並且沒有資料統計相關功能,目前可以在啟動時將所有資料都放入快取中。

5.3 實現快取預熱


1) 利用Docker安裝Redis

docker run --name redis -p 6379:6379 -d redis redis-server --appendonly yes

本地主機RDM工具遠端連線虛擬機器中docker安裝的redis服務

2)在item-service服務中引入Redis依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

3)配置Redis地址

spring:
  redis:
    host: 10.193.193.141
  1. 編寫初始化類

快取預熱需要在專案啟動時完成,並且必須是拿到RedisTemplate之後。

這裡我們利用InitializingBean介面來實現,因為InitializingBean可以在物件被Spring建立並且成員變數全部注入後執行。

package com.heima.item.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.heima.item.pojo.Item;
import com.heima.item.pojo.ItemStock;
import com.heima.item.service.IItemService;
import com.heima.item.service.IItemStockService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 實現redis快取預熱
 * 專案啟動那一刻,就會建立RedisHandler這個Bean,並注入redisTemplate物件,然後執行afterPropertiesSet()
 */
@Component
public class RedisHandler implements InitializingBean {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IItemService itemService;
    @Autowired
    private IItemStockService stockService;

    /**
     * from jackson
     * spring裡一個預設的json處理工具ObjectMapper
     * 靜態常量,工具
     */
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 初始化快取
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        // 1. 查詢商品資訊(此處理應僅查詢熱點資料,實際因為此次演示資料不多,所以全查全放到快取中)
        List<Item> itemList = itemService.list();
        // 2. 放入快取
        for (Item item : itemList) {
            // 2.1 item序列化為json
            String json = MAPPER.writeValueAsString(item);
            // 2.2 存入redis
            redisTemplate.opsForValue().set("item:id:"+item.getId(), json); //key=字首"item:id:"+id,value=json
        }
        // 3. 查詢商品庫存資訊(同上)
        List<ItemStock> stockList = stockService.list();
        // 4. 放入快取
        for (ItemStock stock : stockList) {
            // 4.1 stock序列化為json
            String json = MAPPER.writeValueAsString(stock);
            // 4.2 存入redis
            redisTemplate.opsForValue().set("item:stock:id:"+stock.getId(), json);
        }
    }
}

重啟8081和8082埠的item-service服務(或者只重啟其中一個也可以)

可以從日誌中看到在服務啟動那一刻有資料查詢;查詢完後會被放入redis快取中

現在來看一下RDM中被快取好的資料

老師演示的效果(不知為啥我的竟然有亂碼,難道是編碼格式不對?)

PS:此問題已解決,見下一小結https://www.cnblogs.com/yppah/p/16226273.html末尾