ruoyi(若依Vue3)移除Redis緩存實操方案_第1頁
ruoyi(若依Vue3)移除Redis緩存實操方案_第2頁
ruoyi(若依Vue3)移除Redis緩存實操方案_第3頁
ruoyi(若依Vue3)移除Redis緩存實操方案_第4頁
ruoyi(若依Vue3)移除Redis緩存實操方案_第5頁
已閱讀5頁,還剩9頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

若依框架(ruoyi)Vue3+ElementPlus移除Redis緩存方案(完整步驟)目錄一、 背景介紹 2二、 部署問題 2三、 需要解決的問題 3四、 實施步驟 31. 更改ruoyi-admin目錄下application.yml文件 32. 更改ruoyi-framework下的RedisConfig文件 33. 修改RedisCache類 64. 登錄校驗時刪除過期緩存,防止占用內(nèi)存 85. 處理用戶信息垃圾緩存問題 96. 處理在線用戶列表 97. 處理緩存讀取問題 108. 更改SysConfigServiceImpl文件 129. 去掉redisCache.setCacheObject方法后兩個參數(shù) 1310. 處理異常問題 13五、 項目啟動效果圖 14六、 系統(tǒng)擴展集成了MybatisPlus 14背景介紹公司運維的某些項目需要進行“國產(chǎn)化”改造,經(jīng)過反復(fù)技術(shù)選型,終合考慮了技術(shù)的先進性、可維護性,并著重考慮后期能更好地進行二次開發(fā),最終選擇了若依(RuoYI)這個開源框架,這個框架的Vue3版本,核心使用了Vue3、ElementPlus、Vite構(gòu)建工具等相對較新的技術(shù),無關(guān)的功能相對較少,通過對其改造,在此基礎(chǔ)上進行二次開發(fā)后,有助于掌握當(dāng)前主流的開發(fā)技術(shù)和構(gòu)建模式,能夠為公司的其他項目后續(xù)改造儲備相關(guān)技術(shù)。部署問題項目部署過程依據(jù)官方文檔還算順利,但編譯和啟動過程中,總是提示在6379端口的服務(wù)啟動失敗,后來知道是redis緩存服務(wù)的原因,因為大部分項目比較小,沒有并發(fā)問題需要考慮,如果再部署Redis服務(wù)器的話,無疑增加了額外的運維成本和不穩(wěn)定性,于是決定采用ConcurrentHashMap對其進行替換,但在實際操作過程中遇到了不少問題,網(wǎng)上查的的解決方案沒有一個是完整可用的,所以在成功解決這個問題后,就此形成一個完整的記錄文檔,供有此需求的人參考。需要解決的問題用ConcurrentHashMap替換后,項目運行不能有任何報錯系統(tǒng)緩存模塊和在線用戶模塊能正常顯示數(shù)據(jù)解決ConcurrentHashMap非正常退出所產(chǎn)生的冗余緩存等一系列不合理問題實施步驟更改ruoyi-admin目錄下application.yml文件注釋掉文件內(nèi)的redis配置,如下圖更改ruoyi-framework下的RedisConfig文件注釋掉@Bean、@Configuration和@EnableCaching注解在ruoyi-common的core/redis下新建MyCache類packagemon.core.redis;

importorg.springframework.cache.Cache;

importorg.springframework.cache.support.SimpleValueWrapper;

importorg.springframework.stereotype.Component;

importjava.util.Collection;

importjava.util.HashMap;

importjava.util.Map;

importjava.util.Objects;

importjava.util.concurrent.Callable;

importjava.util.concurrent.ConcurrentHashMap;

@Component

publicclassMyCacheimplementsCache{

privateMap<String,Object>storage=newConcurrentHashMap<>();

/**

*每個緩存生效時間12小時

*/

//publicstaticfinallongCACHE_HOLD_TIME_12H=12*60*60*1000L;

@Override

publicStringgetName(){

returnnull;

}

@Override

publicObjectgetNativeCache(){

returnnull;

}

@Override

public<T>Tget(Objectkey,Class<T>type){

returnnull;

}

@Override

public<T>Tget(Objectkey,Callable<T>valueLoader){

returnnull;

}

@Override

publicvoidclear(){

}

publicbooleanhasKey(Stringkey){

returnstorage.containsKey(key);

}

@Override

publicValueWrapperget(Objectkey){

Stringk=key.toString();

Objectvalue=storage.get(k);

//注意返回的數(shù)據(jù),要和存放時接收到數(shù)據(jù)保持一致,要將數(shù)據(jù)反序列化回來。

returnObjects.isNull(value)?null:newSimpleValueWrapper(value);

}

@Override

publicvoidput(Objectkey,Objectvalue){

if(Objects.isNull(value)){

return;

}

storage.put(key.toString(),value);

}

@Override

publicvoidevict(Objectkey){

storage.remove(key.toString());

}

//刪除集合

publicbooleandeleteObject(Collection<String>collection){

collection.forEach(item->{

storage.remove(item);

});

returntrue;

}

//獲取所有的keys

publicCollection<String>keys(finalStringpattern){

//editbywjl鍵值查詢

StringpatternStr=pattern.replace(":","");

Map<String,Object>myMap=newHashMap<>();

Collection<String>keys=storage.keySet();

for(Stringkey:keys){

if(key.contains(patternStr)){

myMap.put(key,storage.get(key));

}

}

returnmyMap.keySet();

}

}修改RedisCache類整個文件,使用下面代碼段覆蓋packagemon.core.redis;

importjava.util.Collection;

importjava.util.concurrent.TimeUnit;

importorg.springframework.cache.Cache;

importorg.springframework.stereotype.Component;

importjavax.annotation.Resource;

/**

*springredis工具類

*

*@authorruoyi

**/

@SuppressWarnings(value={"unchecked","rawtypes"})

@Component

publicclassRedisCache

{

@Resource

publicMyCachemyCache;

/**

*緩存基本的對象,Integer、String、實體類等

*

*@paramkey緩存的鍵值

*@paramvalue緩存的值

*/

public<T>voidsetCacheObject(finalStringkey,finalTvalue)

{

myCache.put(key,value);

}

/**

*判斷key是否存在

*

*@paramkey鍵

*@returntrue存在false不存在

*/

publicBooleanhasKey(Stringkey)

{

returnmyCache.hasKey(key);

}

/**

*獲得緩存的基本對象。

*

*@paramkey緩存鍵值

*@return緩存鍵值對應(yīng)的數(shù)據(jù)

*/

public<T>TgetCacheObject(finalStringkey)

{

Cache.ValueWrappervalueWrapper=myCache.get(key);

if(valueWrapper==null){

returnnull;

}else{

return(T)valueWrapper.get();

}

}

/**

*刪除單個對象

*

*@paramkey

*/

publicbooleandeleteObject(finalStringkey)

{

myCache.evict(key);

returntrue;

}

/**

*刪除集合對象

*

*@paramcollection多個對象

*@return

*/

publicbooleandeleteObject(finalCollectioncollection)

{

returnmyCache.deleteObject(collection);

}

/**

*獲得緩存的基本對象列表

*

*@parampattern字符串前綴

*@return對象列表

*/

publicCollection<String>keys(finalStringpattern)

{

returnmyCache.keys(pattern);

}

}登錄校驗時刪除過期緩存,防止占用內(nèi)存更改ruoyi-framework目錄下web/service/TokenService文件,使用下面方法替換原有方法/**

*驗證令牌有效期,相差不足20分鐘,自動刷新緩存

*

*@paramloginUser

*@return令牌

*/

publicvoidverifyToken(LoginUserloginUser)

{

longexpireTime=loginUser.getExpireTime();

longcurrentTime=System.currentTimeMillis();

if(expireTime-currentTime<0){

//editbywjl過期刪除token

StringuserKey=getTokenKey(loginUser.getToken());

redisCache.deleteObject(userKey);

thrownewServiceException("登錄超時",HttpStatus.UNAUTHORIZED);

}

elseif(expireTime-currentTime<=MILLIS_MINUTE_TEN)

{

refreshToken(loginUser);

}

}處理用戶信息垃圾緩存問題繼續(xù)更改上一條修改過的TokenService文件,修改文件當(dāng)中的createToken(LoginUserloginUser)方法保證每個用戶只緩存一個鍵值對,防止反復(fù)登錄或直接關(guān)閉瀏覽器產(chǎn)生垃圾緩存//Stringtoken=IdUtils.fastUUID();

Stringtoken="WF"+String.format("%08d",loginUser.getUserId());處理在線用戶列表更改ruoyi-admin目錄下\src\main\java\com\ruoyi\web\controller\monitor\SysUserOnlineController.java文件,找到下面方法,可直接替換publicTableDataInfolist(Stringipaddr,StringuserName)

{

Collection<String>keys=redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY);

List<SysUserOnline>userOnlineList=newArrayList<SysUserOnline>();

for(Stringkey:keys)

{

//editbywjl在線用戶

if(key.indexOf(CacheConstants.LOGIN_TOKEN_KEY)>-1){

LoginUseruser=redisCache.getCacheObject(key);

if(StringUtils.isNotEmpty(ipaddr)&&StringUtils.isNotEmpty(userName))

{

userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr,userName,user));

}

elseif(StringUtils.isNotEmpty(ipaddr))

{

userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr,user));

}

elseif(StringUtils.isNotEmpty(userName)&&StringUtils.isNotNull(user.getUser()))

{

userOnlineList.add(userOnlineService.selectOnlineByUserName(userName,user));

}

else

{

userOnlineList.add(userOnlineService.loginUserToUserOnline(user));

}

}

}

Collections.reverse(userOnlineList);

userOnlineList.removeAll(Collections.singleton(null));

returngetDataTable(userOnlineList);

}處理緩存讀取問題更改ruoyi-admin目錄下com\ruoyi\web\controller\monitor\CacheController.java由于更改太多,直接使用下面整個類替換packagecom.ruoyi.web.controller.monitor;

importjava.util.ArrayList;

importjava.util.Collection;

importjava.util.List;

importcom.alibaba.fastjson2.JSON;

importmon.core.redis.RedisCache;

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.security.access.prepost.PreAuthorize;

importorg.springframework.web.bind.annotation.DeleteMapping;

importorg.springframework.web.bind.annotation.GetMapping;

importorg.springframework.web.bind.annotation.PathVariable;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.bind.annotation.RestController;

importmon.constant.CacheConstants;

importmon.core.domain.AjaxResult;

importcom.ruoyi.system.domain.SysCache;

/**

*緩存監(jiān)控

*

*@authorruoyi

*/

@RestController

@RequestMapping("/monitor/cache")

publicclassCacheController

{

@Autowired

privateRedisCacheredisCache;

privatefinalstaticList<SysCache>caches=newArrayList<SysCache>();

{

caches.add(newSysCache(CacheConstants.LOGIN_TOKEN_KEY,"用戶信息"));

caches.add(newSysCache(CacheConstants.SYS_CONFIG_KEY,"配置信息"));

caches.add(newSysCache(CacheConstants.SYS_DICT_KEY,"數(shù)據(jù)字典"));

caches.add(newSysCache(CacheConstants.CAPTCHA_CODE_KEY,"驗證碼"));

caches.add(newSysCache(CacheConstants.REPEAT_SUBMIT_KEY,"防重提交"));

caches.add(newSysCache(CacheConstants.RATE_LIMIT_KEY,"限流處理"));

caches.add(newSysCache(CacheConstants.PWD_ERR_CNT_KEY,"密碼錯誤次數(shù)"));

}

@PreAuthorize("@ss.hasPermi('monitor:cache:list')")

@GetMapping("/getNames")

publicAjaxResultcache()

{

returnAjaxResult.success(caches);

}

@PreAuthorize("@ss.hasPermi('monitor:cache:list')")

@GetMapping("/getKeys/{cacheName}")

publicAjaxResultgetCacheKeys(@PathVariableStringcacheName)

{

//editbywjl緩存列表

Collection<String>keys=redisCache.keys(cacheName);

returnAjaxResult.success(keys);

}

@PreAuthorize("@ss.hasPermi('monitor:cache:list')")

@GetMapping("/getValue/{cacheName}/{cacheKey}")

publicAjaxResultgetCacheValue(@PathVariableStringcacheName,@PathVariableStringcacheKey)

{

//editbywjl通過鍵值獲取緩存

ObjectcacheValue=redisCache.getCacheObject(cacheKey);

SysCachesysCache=newSysCache(cacheName,cacheKey,JSON.toJSONString(cacheValue));

returnAjaxResult.success(sysCache);

}

@PreAuthorize("@ss.hasPermi('monitor:cache:list')")

@DeleteMapping("/clearCacheName/{cacheName}")

publicAjaxResultclearCacheName(@PathVariableStringcacheName)

{

Collection<String>cacheKeys=redisCache.keys(cacheName+"*");

redisCache.deleteObject(cacheKeys);

returnAjaxResult.success();

}

@PreAuthorize("@ss.hasPermi('monitor:cache:list')")

@DeleteMapping("/clearCacheKey/{cacheKey}")

publicAjaxResultclearCacheKey(@PathVariableStringcacheKey)

{

redisCache.deleteObject(cacheKey);

returnAjaxResult.success();

}

@PreAuthorize("@ss.hasPermi('monitor:cache:list')")

@DeleteMapping("/clearCacheAll")

publicAjaxResultclearCacheAll()

{

Collection<String>cacheKeys=redisCache.keys("*");

redisCache.deleteObject(cacheKeys);

returnAjaxResult.success();

}

}更改SysConfigServiceImpl文件在ruoyi-system目錄下@Override

publicStringselectConfigByKey(StringconfigKey)

{

//StringconfigValue=Convert.toStr(redisCache.getCacheObject(getCacheKey(configK

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論