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