您好,登錄后才能下訂單哦!
今天小編給大家分享一下redis怎么實現頁面實時更新自動上線的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
某些頁面需要配置廣告或活動宣傳圖,廣告或活動需滿足隨時上下線、過期自動下線及到時自動上線。
如:現在時間2019-2-22 16:16:13,要在支付完成頁面配置領獎活動,活動要在2019-3-10 00:00:00準時上線,在2019-3-30 23:59:59結束活動。
所以要的效果是,在活動上線前的任意時刻配置完活動后,頁面到時間自動上線這個活動。也可能會是其他的多個活動或廣告,每個頁面廣告的個數可變,不同上下線時間可不同,其他頁面也需要實現這樣的功能,頁面與頁面之間的活動不一定一樣。
需求簡單的幾句話,那么我們來具體的分析一下。
廣告或活動宣傳圖
隨時上下線、過期自動下線及到時自動上線
每個頁面廣告的個數可變
不同廣告上下線時間可不同
頁面與頁面之間的活動不一定一樣
1、【廣告或活動宣傳圖】
要為不同頁面設置不同的廣告,有的頁面廣告可能一樣,也就是廣告會復用,所有要有廣告表。
2、【每個頁面廣告的個數可變】【不同廣告上下線時間可不同】【頁面與頁面之間的活動不一定一樣】
頁面可配置多個廣告,所有要有頁面配置表,以及廣告和頁面的關系表,即頁面廣告表。
頁面配置表主要配置頁面的廣告個數,實現【每個頁面廣告的個數可變】,頁面廣告表主要配置頁面的每個廣告上下線時間,實現【不同廣告上下線時間可不同】
簡單分析后得出如下表結構:廣告表adv,頁面配置表page_config,頁面廣告表page_adv
這些頁面配置的廣告在一段時間內是不會變的,如果頁面請求次數較多,廣告查詢次數就會很頻繁,對數據庫造成不必要的壓力。所以可以引入緩存,降低數據庫請求次數,緩解數據庫壓力。這里使用的Redis。
何時入緩存?
可以選擇在服務啟動時異步把已在上下線時間區間內的廣告先加載至緩存,或選擇在請求時取緩存,緩存內沒有時再查庫然后放緩存。緩存時間視情況而定。
這里選擇的是,項目啟動時異步把符合條件的頁面廣告配置信息存入Redis,那些還沒到指定時間的先不放Redis,等到訪問頁面加載廣告時,先查Redis,若無則按條件(>=nowtime)查庫,查到后存Redis。
在接口中拿到廣告配置信息后,判斷當前時間是否在配置的時間區間內,由于一個頁面配置多個廣告,不同廣告時間也不同,所以要迭代,把符合的返回,有過期的就做標記,然后把整個頁面的配置信息在Redis里刪除。(或者不選擇在啟動時加載,就在用戶請求時加入緩存,但是下面的第1步的方法在刷新加載時會用到,故不能刪)
a、查詢所有pageId
SELECT pageId FROM page_config page_adv WHERE nowtime<=endtime AND GROUP BY pageId
兩個表內連接,得List<pageId>,得到的都是配置的有廣告的并且廣告還沒過期的pageId。
b、查詢pegeId對應的廣告圖片及跳轉鏈接
SELECT 字段名 FROM page_adv adv WHERE begintime<=nowtime<=endtime AND pageId={#pageId}
然后把查到的配置信息List<adv>(為空時不做操作),以pageId為KEY放入緩存。
按標準的控制層,業務層,數據訪問層寫,第一步中的邏輯就是在業務層完成的。
控制層:
控制層接參pageId,調用業務層查詢對應頁面配置的廣告信息,判空,直接返回狀態碼0,即無廣告前端不展示。
不為空就根據業務邏輯處理數據(如img的URL加域名),然后返回狀態碼1,前端展示廣告。這里控制層還可以加邏輯,迭代廣告list,把當前時間在廣告起始時間內的返回,不在的不返回,并且只要有一個廣告過期,就把這個頁面的廣告list緩存清掉。這個邏輯是把過期的清掉。
業務層:
先取緩存,沒有再查庫判斷不為空(本頁面配置的有廣告),放入緩存(pageId為KEY),然后返回。
數據訪問層:
SQL:
SELECT 字段名 FROM page_config adv page_adv WHERE begintime<=nowtime<=endtime AND pageId=#{pageId}
三表聯查,根據pageId查詢當前頁面配置的廣告活動信息(已在廣告活動時間內)
為什么使用刷新加載?
因為有這樣的場景:給頁面A配置了一個廣告(當前時間在廣告的起始時間內),那么這個頁面的廣告已經在緩存里了,假如此時A頁面要新加一個廣告,在后臺配置后如果不做其他操作,這個廣告不會顯示(假設緩存時間較長,為一天),因為庫更新了,緩存沒有同步更新。
解決方案
使用Redis的發布訂閱機制實現緩存的刷新加載,使新配置的廣告及時能夠顯示。刷新加載的回調方法即第1步中的方法。
想一想,目前的實現存在什么問題?
存在的問題
假如有頁面需要配置廣告,但是還沒有配(前端已經開發完上線,每次都會調接口查廣告信息),那么數據庫肯定查不到,緩存也沒有。如果這個頁面訪問量很大,那么緩存沒命中就查庫,這樣對庫的壓力就會很大,這就是緩存穿透,請求上來了很容易擊垮數據庫。那怎么辦呢?
解決方案
當頁面沒有配置廣告時,在緩存存標志,查詢時先看標志,在決定是否往下走。
具體方案
這時,上面的第1步就要改了。
1、首先改第1步的步驟a的SQL,把所有的pageId都查詢出來。
使用左連接
SELECT pageId FROM page_config LEFT JOIN page_adv ON ... GROUP BY pageId
或者干脆查page_config
SELECT pageId FROM page_config
目的是把已在page_config表中配置,但關系表中page_adv未配置廣告的pageId也查出來,這樣才能給未配置廣告的pageId在緩存里放標志
2、第1步的步驟b的SQL改為
SELECT 字段名 FROM page_adv adv WHERE nowtime<=endtime AND pageId={#pageId}
然后把查到的配置信息放入緩存之前判斷【為空時的不做操作】改為【為空時存入一個標志】假如這個標志KEY為pageId+"_EMPTY_FLAG",value為"DB_IS_NULL"
為什么只判斷小于結束時間
因為如果該頁面配置的廣告開始時間大于當前時間,那么這個是查不到的,會被處理為DATABASE_IS_NULL,如果在這個標志還沒失效之前就到了配置的開始時間了,那么這個廣告不會被展示。所有要讓未到開始時間的也放入緩存,然后讓控制層去判斷在不在時間區間。
3、所以要在第2步也修改一下
在業務層里取緩存中的廣告列表之前,先從緩存取pageId+"EMPTY_FLAG"的value判斷為"DB_IS_NULL"直接返回空,這樣就能避免緩存穿透的問題了。
繼續修改第2步的業務層,查庫的SQL同樣要改:
SELECT 字段名 FROM page_config adv page_adv WHERE nowtime<=endtime AND pageId=#{pageId}
然后判斷為空的話,同上面的黃字那樣處理。
4、最后,第3步的刷新加載調的是第1步的方法,不用改。
當然這個緩存穿透的優化方案只是其中一種。還可以這樣:
1、控制層攔截:根據pageId查詢page_adv表,查不到說明沒配置,直接返回。
2、page_config 表增加字段,表示當前頁面已經配置的廣告個數,默認0,每配置一個該字段加1,把大于0的pageId緩存起來,調接口時前判斷在不在緩存里。
以上就是“redis怎么實現頁面實時更新自動上線”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。