需求描述
某些頁面需設定廣告或活動宣傳圖,廣告或活動需滿足隨時上下線、過期自動下線及到時自動上線。
如:現在時間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步的方法在刷新加載時會用到,故不能刪)
具體實現
步驟1、專案啟動時先把頁面廣告設定資訊存入Redis
a、查詢所有pageId
SELECT pageId FROM page_config page_adv WHERE nowtime<p>兩個表內連接,得List<pageid>,得到的都是配置的有廣告的且廣告還沒過期的pageId。 </pageid></p><p>b、查詢pegeId對應的廣告圖片及跳轉連結</p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_adv adv WHERE begintime<p>然後把查到的設定資訊List<adv>(空時不做動作),以pageId為KEY放入緩存。 </adv></p><h4 id="步驟-給前端寫介面查詢頁面廣告">步驟2、給前端寫介面查詢頁面廣告</h4><p>按標準的控制層,業務層,資料存取層寫,第一步中的邏輯就是在業務層完成的。 </p><p>控制層:</p><p>控制層接參pageId,呼叫業務層查詢對應頁面配置的廣告訊息,判空,直接回傳狀態碼0,即無廣告前端不展示。 </p><p>不為空就依照業務邏輯處理資料(如img的URL加網域),然後回傳狀態碼1,前端展示廣告。這裡控制層還可以加邏輯,迭代廣告list,把當前時間在廣告起始時間內的返回,不在的不返回,並且只要有一個廣告過期,就把這個頁面的廣告list緩存清掉。這個邏輯是把過期的清掉。 </p><p>業務層:</p><p>先取緩存,沒有再查庫判斷不為空(本頁配置的有廣告),放入快取(pageId為KEY),然後返回。 </p><p>資料存取層:</p><p>SQL:</p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_config adv page_adv WHERE begintime<p>三表聯查,根據pageId查詢目前頁面配置的廣告活動資訊(已在廣告活動時間內)</p><h4 id="第-步-刷新載入">第3步、刷新載入</h4><p>為什麼要使用刷新載入? </p><p>因为有这样的场景:给页面A配置了一个广告(当前时间在广告的起始时间内),那么这个页面的广告已经在缓存里了,假如此时A页面要新加一个广告,在后台配置后如果不做其他操作,这个广告不会显示(假设缓存时间较长,为一天),因为库更新了,缓存没有同步更新。</p><p>解决方案</p><p>使用Redis的发布订阅机制实现缓存的刷新加载,使新配置的广告及时能够显示。刷新加载的回调方法即第1步中的方法。</p><h3 id="进一步优化">进一步优化</h3><p>想一想,目前的实现存在什么问题?</p><p>存在的问题</p><p>假如有页面需要配置广告,但是还没有配(前端已经开发完上线,每次都会调接口查广告信息),那么数据库肯定查不到,缓存也没有。如果这个页面访问量很大,那么缓存没命中就查库,这样对库的压力就会很大,这就是缓存穿透,请求上来了很容易击垮数据库。那怎么办呢?</p><p>解决方案</p><p>当页面没有配置广告时,在缓存存标志,查询时先看标志,在决定是否往下走。</p><p>具体方案</p><p>这时,上面的第1步就要改了。</p><p>1、首先改第1步的步骤a的SQL,把所有的pageId都查询出来。</p><p>使用左连接</p><pre class="brush:php;toolbar:false">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<p>然后把查到的配置信息放入缓存之前判断【为空时的不做操作】改为【为空时存入一个标志】假如这个标志KEY为pageId+"_EMPTY_FLAG",value为"DB_IS_NULL"</p><p>为什么只判断小于结束时间</p><p>因为如果该页面配置的广告开始时间大于当前时间,那么这个是查不到的,会被处理为DATABASE_IS_NULL,如果在这个标志还没失效之前就到了配置的开始时间了,那么这个广告不会被展示。所有要让未到开始时间的也放入缓存,然后让控制层去判断在不在时间区间。</p><p>3、所以要在第2步也修改一下</p><p>在业务层里取缓存中的广告列表之前,先从缓存取pageId+"EMPTY_FLAG"的value判断为"DB_IS_NULL"直接返回空,这样就能避免缓存穿透的问题了。</p><p>继续修改第2步的业务层,查库的SQL同样要改:</p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_config adv page_adv WHERE nowtime<p>然后判断为空的话,同上面的黄字那样处理。</p><p>4、最后,第3步的刷新加载调的是第1步的方法,不用改。<br><br>当然这个缓存穿透的优化方案只是其中一种。还可以这样:</p><p>1、控制层拦截:根据pageId查询page_adv表,查不到说明没配置,直接返回。</p><p>2、page_config 表增加字段,表示当前页面已经配置的广告个数,默认0,每配置一个该字段加1,把大于0的pageId缓存起来,调接口时前判断在不在缓存里。</p>
以上是redis怎麼實現頁面即時更新自動上線的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Redis支持多種數據結構,具體包括:1.字符串(String),適合存儲單一值數據;2.列表(List),適用於隊列和棧;3.集合(Set),用於存儲不重複數據;4.有序集合(SortedSet),適用於排行榜和優先級隊列;5.哈希表(Hash),適合存儲對像或結構化數據。

Redis計數器是一種使用Redis鍵值對存儲來實現計數操作的機制,包含以下步驟:創建計數器鍵、增加計數、減少計數、重置計數和獲取計數。 Redis計數器的優勢包括速度快、高並發、持久性和簡單易用。它可用於用戶訪問計數、實時指標跟踪、遊戲分數和排名以及訂單處理計數等場景。

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

Redis 集群中使用 zset:zset 是一種有序集合,將元素與評分關聯。分片策略: a. 哈希分片:根據 zset 鍵的哈希值分佈。 b. 範圍分片:根據元素評分劃分為範圍,並將每個範圍分配給不同的節點。讀寫操作: a. 讀操作:如果 zset 鍵屬於當前節點的分片,則在本地處理;否則,路由到相應的分片。 b. 寫入操作:始終路由到持有 zset 鍵的分片。

如何清空 Redis 數據:使用 FLUSHALL 命令清除所有鍵值。使用 FLUSHDB 命令清除當前選定數據庫的鍵值。使用 SELECT 切換數據庫,再使用 FLUSHDB 清除多個數據庫。使用 DEL 命令刪除特定鍵。使用 redis-cli 工具清空數據。

Redis數據過期策略有兩種:定期刪除:定期掃描刪除過期鍵,可通過 expired-time-cap-remove-count、expired-time-cap-remove-delay 參數設置。惰性刪除:僅在讀取或寫入鍵時檢查刪除過期鍵,可通過 lazyfree-lazy-eviction、lazyfree-lazy-expire、lazyfree-lazy-user-del 參數設置。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

WebStorm Mac版
好用的JavaScript開發工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)