天天看點

Spring Boot實作分布式微服務開發 -- Redis緩存安全防範(緩存穿透、雪崩及緩存擊穿)

最近已經推出了好幾篇SpringBoot+Dubbo+Redis+Kafka實作電商的文章,今天再次回到分布式微服務項目中來,在開始寫今天的系列五文章之前,我先回顧下前面的内容。

系列(一):主要說了使用IDEA對SpringBoot項目的建立,SpringBoot架構下Web項目Maven的基本依賴及實作。

系列(二):主要講了Maven父子級項目建立依賴、分環境部署配置及服務端口号統一配置,Dubbo的內建接入、服務層(提供者)分子產品實作,提供者(四個)和消費者(一個)的配置及服務調用,微服務落地實作。

系列(三):開始講了項目及依賴的版本号統一配置管理(子子產品和第三方依賴Jar),資料庫的連接配接配置及Redis接入、分布式緩存實作。

系列(四):接口安全實作(防惡意請求、資料篡改等),過濾器配置及簽名、token檢驗攔截、Aop簽名實作、防SQL注入等。

學而時習之,不亦說乎。作為我本次推出的系列文章,目的很簡單,就是旨意幫助那些不懂分布式開發微服務落地的小夥伴們。目前的IT市場,分布式開發微服務落地已成為主流。SpringBoot,Dubbo,Zookeeper,Redis,Kafka,SpringCloud等也是面試中常問的話題,如果你想在這個行業混下去,這些已經是你必須要學的基礎技術知識了,接下來我會根據我近兩年的分布式微服務開發經驗推出更多的文章。但在前面或接下來的文章中如果有說的不到之處,還希望大家多多指點交流(可添加我微信交流),促使我們一起成長進步,做一個合格的技術人。

Spring Boot實作分布式微服務開發 -- Redis緩存安全防範(緩存穿透、雪崩及緩存擊穿)

今天我要講的内容是Redis緩存安全防範以及Kafka的接入實作。如:緩存穿透、雪崩及緩存擊穿如何解決?緩存伺服器當機或重新開機,緩存資料不會被丢失等問題。我們帶着這些問題進入正題。

Redis緩存安全防範

分布式項目使用Redis緩存,極大的提升了應用程式的性能和效率,特别是資料查詢方面。但同時,它也帶來了一些問題。其中,最要害的問題,就是資料的一緻性問題,從嚴格意義上講,這個問題無解。如果對資料的一緻性要求很高,那麼就不能使用緩存。另外的一些典型問題,就是緩存穿透、緩存雪崩和緩存擊穿。

|| 緩存穿透

緩存穿透,是指查詢一個資料庫一定不存在的資料。正常的使用緩存流程大緻是,資料查詢先進行緩存查詢,如果key不存在或者key已經過期,再對資料庫進行查詢,并把查詢到的對象,放進緩存。如果資料庫查詢對象為空,則不放進緩存。如果使用者發起id為“-1”或id特别大不存在的資料。這時很可能是攻擊者,攻擊會導緻資料庫壓力過大。

解決方案:

1,接口層增加校驗。對id做基礎校驗,id<=0的直接攔截;

2,從緩存取不到的資料,在資料庫中也沒有取到,這時也可以将key-value鍵值對寫為key-null,緩存有效時間可以設定短點,如60秒(設定太長會導緻正常情況也沒法使用),這樣可以防止攻擊使用者反複用同一個id暴力攻擊。

Spring Boot實作分布式微服務開發 -- Redis緩存安全防範(緩存穿透、雪崩及緩存擊穿)

|| 緩存雪崩

緩存雪崩,是指在某一個時間段,緩存集中過期失效。産生雪崩的原因之一,比如馬上就到618了,很快就會迎來一波搶購,這些要搶購的商品在同一時間點(17号23點放入)比較集中的放入了緩存,假設緩存兩個小時。那麼到了淩晨一點鐘的時候,這批商品的緩存就都過期了。而此時對這批商品的通路查詢,都落到了資料庫身上,這時對于資料庫而言,就會帶來極大的壓力。

解決方案:

1,在設定資料緩存有效期時,在時間後加上一個随機因子。

2,分散緩存過期時間,将熱門類資料緩存時間長一點,冷門類的短一點。

3,設定熱點資料永不過期。

Spring Boot實作分布式微服務開發 -- Redis緩存安全防範(緩存穿透、雪崩及緩存擊穿)

|| 緩存擊穿

緩存擊穿,是指一個key非常熱點,高并發集中對這個點進行通路,當這個key在失效的瞬間,持續的大并發就穿破緩存,直接請求資料庫,就像春運期間火車站售票大廳,本來那些設在門口和廣場的自助機可以辦理售票,結果自助機瞬間全部癱瘓,造成大量買票的人湧進售票大廳人工視窗。

解決方案:

1,設定熱點資料永遠不過期;

2,加互斥鎖,互斥鎖參考代碼如下:

Spring Boot實作分布式微服務開發 -- Redis緩存安全防範(緩存穿透、雪崩及緩存擊穿)

|| 緩存資料持久化

Redis提供了将資料定期自動持久化至硬碟的能力,包括RDB和AOF兩種方案,兩種方案分别有其長處和短闆,可以配合起來同時運作,確定資料的穩定性。

RDB

RDB方式是一種快照式的持久化方法,将某一時刻的資料持久化到磁盤中。并在啟動時自動加載rdb檔案,恢複之前儲存的資料。可以在配置檔案中配置Redis進行快照儲存的時機:

save [seconds] [changes]

例如:save 60 100, 會讓Redis每60秒檢查一次資料變更情況,如果發生了100次或以上的資料變更,則進行RDB快照儲存。可以配置多條save指令,讓Redis執行多級的快照儲存政策。Redis預設開啟RDB快照。

AOF

采用AOF持久方式時,Redis會把每一個寫請求都記錄在一個日志檔案裡。在Redis重新開機時,會把AOF檔案中記錄的所有寫操作順序執行一遍,確定資料恢複到最新。AOF預設是關閉的,如要開啟,進行如下配置:

appendonly yes

  • AOF提供了三種fsync配置,always/everysec/no,通過[appendfsync]指定:appendfsync no:不進行fsync,将flush檔案的時機交給OS決定,速度最快;
  • appendfsync always:每寫入一條日志就進行一次fsync操作,資料安全性最高,但速度最慢;
  • appendfsync everysec:折中的做法,交由背景線程每秒fsync一次;

注:項目源碼已共享到Github,如果需要請掃碼關注以下公衆号,并發送“Springboot”擷取。

Spring Boot實作分布式微服務開發 -- Redis緩存安全防範(緩存穿透、雪崩及緩存擊穿)

繼續閱讀