代碼中如何應對緩存服務器宕機的情況


今天在演練這樣一個場景——假如所有緩存服務器都宕機,而且不能很快恢復,並且假設數據庫服務器能夠支撐,在代碼中如何應對這樣的情況?

之前的做法是在讀緩存的地方捕獲異常並寫入日志,然后直接從數據庫讀取數據;在寫緩存的地方捕獲異常並寫入日志,繼續后續處理。這樣看起來不錯,雖然緩存服務器宕機,但程序可以繼續工作,雖然速度慢一些,但不會讓網站服務中斷,然后只要把緩存服務器恢復即可。

但是如果緩存服務器宕機時,訪問量很大,每一個操作緩存的地方都拋異常、寫日志,這是兩個開銷很大的操作,大量的這樣的操作會給Web服務器帶來很大的壓力。有沒有更好的解決方法呢?

當操作緩存時拋出了第一個異常,我們就已經知道緩存服務器發生了故障。接下來對緩存的任何操作不僅沒有必要,而且由此產生的異常會帶來額外的開銷、影響性能。只要我們通過一種方式在知道緩存服務器發生故障的第一時間通知后續緩存操作代碼不要進行緩存操作,就能解決這個問題。

我們想到的一個解決方法是通過全局靜態變量,該全局靜態變量保存緩存服務器當前可用狀態,只要有一個操作緩存的地方出現異常就將該變量置為不可用狀態,並寫日志、發通知。每一個操作緩存的地方在操作前先檢查一下這個全局靜態變量,一發現緩存服務器不可用,就放棄操作緩存,進入無緩存情況下的操作流程。當我們得知緩存服務器宕機后,先專心把緩存服務器恢復正常運行,然后更新一下這個全局靜態變量即可。

這又是一個看起來不錯的解決方法。但是全局靜態變量只能在當前應用程序的當前進程中全局,無法在Web Farm(比如使用負載均衡,同一個應用程序運行於多台服務器上)與Web Garden(同一個應用程序運行於同一台服務器的多個進程中)的場景中全局。所以采用這個解決方法,緩存服務器宕機時,每個進程都要進行捕獲異常、設置全局靜態變量的操作,雖然不是最佳解決方法,但總比異常滿天飛要好很多。還有一個更頭疼的問題,就是在緩存服務器恢復正常后,如何將這些全局靜態變量恢復為可用狀態?無法代碼進入每一個進程中進行操作,目前我們只想到一個解決方法——重啟應用程序(如果是IIS,回收應用程序池)。

有沒有更好的解決方法呢?繼續思考,也期待你的良計妙策。

【更新】

改進修改全局靜態變量的方式,通過定時執行的代碼檢查緩存服務器的狀態。如果緩存服務器不可用,將全局靜態變量置為不可用狀態;如果緩存服務器可用,並且全局靜態變量的值為不可用狀態,則將全局靜態變量置為可用狀態。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM