網(wǎng)站的問題主要是來自龐大的訪問用戶,高并發(fā)的訪問量和海量數(shù)據(jù)。在這個科技時代,由于互聯(lián)網(wǎng)的開放性,使得互聯(lián)網(wǎng)網(wǎng)站更容易受到攻擊,無論大型小型還是打醬油的網(wǎng)站,幾乎都會受到黑客的侵害。
面對這些危機問題,許多人都會第一時間想到用服務(wù)器來預(yù)防,現(xiàn)在市面上的服務(wù)器的防御機制大多是集群防護,集群防護是指整個機房的防護,也是與其他人一起共享的這幾個G的防護。比如說集群防護100G,其實真實的防護還不如10G的單機防御。只看數(shù)值不注重真實,往往會誤入歧途,以為自己賺到了,其實是被坑了。
方案:
防御吧安盾立體式防御
它是可以解決所有網(wǎng)站可能會出現(xiàn)的一切安全問題。例如最常見的網(wǎng)站的高并發(fā)量,以及網(wǎng)站遭受到攻擊等問題。防御吧安盾立體式防護可以幫助網(wǎng)站加速以及防御,隱藏源站服務(wù)器IP,有效解決網(wǎng)站并發(fā)量。
優(yōu)勢:
1、有立體式防護管理后臺,可以自主設(shè)置緩存規(guī)則和緩存時間,可自主調(diào)整CC策略。
2、多節(jié)點分布加強網(wǎng)站的穩(wěn)定性,網(wǎng)站穩(wěn)定百度蜘蛛爬行抓取數(shù)據(jù)正常,網(wǎng)站排名自然就會提高。
3、隱藏網(wǎng)站服務(wù)器IP地址,確保網(wǎng)站服務(wù)器不受到任何影響。
4、防御DDOS、無視CC。
高并發(fā)的優(yōu)化需要借鑒簡書的一位作者
高并發(fā)優(yōu)化
高并發(fā)除了需要對服務(wù)器進(jìn)行垂直擴展和水平擴展之外,作為后端開發(fā)可以通過高并發(fā)優(yōu)化,保證業(yè)務(wù)在高并發(fā)的時候能夠穩(wěn)定的運行,避免業(yè)務(wù)停滯帶來的損失,給用戶帶來不好的體驗
緩存:
服務(wù)端緩存
內(nèi)存數(shù)據(jù)庫
redis
memcache
方式
優(yōu)先緩存
穿透 DB 問題
只讀緩存
更新 / 失效刪除
注意
內(nèi)存數(shù)據(jù)庫的分配的內(nèi)存容量有限,合理規(guī)劃使用,濫用最終會導(dǎo)致內(nèi)存空間不足
緩存數(shù)據(jù)需要設(shè)置過期時間,無效 / 不使用的數(shù)據(jù)自動過期
壓縮數(shù)據(jù)緩存數(shù)據(jù),不使用字段不添加到緩存中
根據(jù)業(yè)務(wù)拆分布式部署緩存服務(wù)器
客戶端緩存
方式
客戶端請求數(shù)據(jù)接口,緩存數(shù)據(jù)和數(shù)據(jù)版本號,并且每次請求帶上緩存的數(shù)據(jù)版本號
服務(wù)端根據(jù)上報的數(shù)據(jù)版本號與數(shù)據(jù)當(dāng)前版本號對比
版本號一樣不返回數(shù)據(jù)列表,版本號不一樣返回最新數(shù)據(jù)和最新版本號
場景:
更新頻率不高的數(shù)據(jù)
服務(wù)端緩存架構(gòu)圖
huancun_pt.png
場景
多級緩存
雖然Redis集群這種緩存的性能已經(jīng)很高了,但是也避免不了網(wǎng)絡(luò)消耗,在高并發(fā)系統(tǒng)中,這些消耗是可能會引起很嚴(yán)重后果的,也需要盡量減少?梢钥紤]多級緩存,將一些變更頻率非常低的數(shù)據(jù)放入應(yīng)用內(nèi)緩存,這樣就可以在應(yīng)用內(nèi)直接處理了,相比使用集中式緩存來說,在高并發(fā)場景還是能夠提高很大效率的,可以參考【cache-redis-caffeine-spring-boot-starter】實現(xiàn)兩級緩存,也可以參考開源中國的J2Cache,支持多種兩級緩存的方式。需要注意的就是緩存失效時一級緩存的清理,因為一級緩存是在應(yīng)用內(nèi),對于集群部署的系統(tǒng),應(yīng)用之間是沒法直接通信的,只能借助其他工具來進(jìn)行通知并清理一級緩存。如利用Redis的發(fā)布訂閱功能來實現(xiàn)同一應(yīng)用不同節(jié)點間的通信
CDN
CDN也是一種緩存,只是主要適用于一些靜態(tài)資源,比如:css、js、png圖片等,前端會使用的較多。在一些場景下,可以結(jié)合動靜分離、前后端分離,將前端資源全部放入CDN中,能夠很大程度提高訪問效率。需要注意的是前端靜態(tài)資源是可能會更新的,當(dāng)有更新的時候需要刷新CDN緩存。或者另一種策略是在靜態(tài)資源的地址上增加一個類似版本號的標(biāo)志,這樣每次修改后的路徑就會不一樣,上線后CDN就會直接回源到自己應(yīng)用內(nèi)獲取最新的文件并緩存在CDN中。使用CDN就需要一套比較完善的自動化部署的工具了,不然每次修改后上線就會比較麻煩
前端緩存
前端html中可以配置靜態(tài)資源在前端的緩存,配置后瀏覽器會緩存一些資源,當(dāng)用戶刷新頁面時,只要不是強制刷新,就可以不用再通過網(wǎng)絡(luò)請求獲取靜態(tài)資源,也能夠一定程度提高頁面的響應(yīng)速度
緩存穿透
當(dāng)使用緩存的時候,如果緩存中查詢不到數(shù)據(jù),就會回源到數(shù)據(jù)庫中查詢。但是如果某些數(shù)據(jù)在數(shù)據(jù)庫中也沒有,如果不做處理,那么每次請求都會回源到數(shù)據(jù)庫查詢數(shù)據(jù)。如果有人惡意利用這種不存在的數(shù)據(jù)大量請求系統(tǒng),那么就會導(dǎo)致大量請求到數(shù)據(jù)庫中執(zhí)行查詢操作。這種情況就叫做緩存穿透。在高并發(fā)場景下更需要防止這種情況的發(fā)生
防止:如果數(shù)據(jù)庫中查詢不到數(shù)據(jù),可以往緩存里放一個指定的值,從緩存中取值時先判斷一下,如果是這個指定的值就直接返回空,這樣就可以都從緩存中獲取數(shù)據(jù)了,從而避免緩存穿透的問題。也可以根據(jù)緩存對象的實際情況,采用兩級緩存的方式,這樣也可以減少緩存設(shè)備的請求量。redis是常用的緩存,但是不能存儲null,因此spring cache模塊中定義了一個NullValue對象,用來代表空值。spring boot中Redis方式實現(xiàn)spring cache是有一些缺陷的(spring boot 1.5.x版本)
緩存雪崩
緩存雪崩主要是指由于緩存原因,大量請求到達(dá)了數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫壓力過大而崩潰。除了上面提到的緩存穿透的原因,還有可能是緩存過期的瞬間有大量的請求需要處理,從緩存中判斷無數(shù)據(jù),然后就直接查詢數(shù)據(jù)庫了。這也是在高并發(fā)場景下比較容易出現(xiàn)的問題
防止:當(dāng)緩存過期時,回源到數(shù)據(jù)庫查詢的時候需要做下處理,如:加互斥鎖。這樣就能夠避免在某個時間點有大量請求到達(dá)數(shù)據(jù)庫了,當(dāng)然也可以對方法級別做限流處理,比如:hystrix、RateLimiter。也可以通過封裝實現(xiàn)緩存在過期前的某個時間點自動刷新緩存。spring cache的注解中有一個sync屬性,主要是用來表示回源到數(shù)據(jù)查詢時是否需要保持同步,由于spring cache只是定義標(biāo)準(zhǔn),沒有具體緩存實現(xiàn),所以只是根據(jù)sync的值調(diào)用了不同的Cache接口的方法,所以需要在Cache接口的實現(xiàn)中注意這點
在緩存的使用方面,會有各種各樣復(fù)雜的情況,建議可以整理一下各種場景并持續(xù)完善,這樣可以在后續(xù)使用緩存的過程中作為參考,也可以避免因為考慮不周全引起的異常,對于員工的培養(yǎng)也是很有好處的。