一般來說,為了應對高並發和高可用,應用服務器都會由單體向分布式演變。而從單體到分布式,通常會遇到四個問題必須要去解決。
一,session共享
首先第一個要解決的就是sesison共享的問題,如下圖。
通常有兩種解決方案,第1種是配置nginx的負載集群策略為ip_hash,第2種是將session存儲到其它地方,一般推薦放到redis中。
第1種方案適合於臨時解決或者是為了兼容歷史項目,但是從應用服務器無狀態的角度考慮,推薦把用戶會話session放到redis,如下圖。
二,本地緩存
如果使用本地緩存,當從單體遷移到集群后,就會面臨緩存同步的問題,如下圖。
最佳實踐是上分布式緩存,既解決了緩存同步的問題,也釋放了應用服務器的內存資源,如下圖。
三,文件服務
應用服務器在上集群之前,文件通常會放在本地,或者單獨的文件服務器上,因為文件服務需要占用大量的硬盤空間,以上兩種方案都無法很好的解決硬盤擴容的問題,最佳實踐是放到雲存儲上,比如阿里雲的OSS,或者騰訊雲的COS上,這樣可以做到按需擴容,如下圖。
四,分布式環境下線程同步問題
在單機環境下,使用lock就可以解決線程同步的問題,一旦上了集群之后,lock就不管用了,這時需要上分布式鎖,分布式鎖的解決方案也有很多,我這里推薦使用redis的setnx,需要注意的是,如果redis是集群部署的,需要考慮這種情形:假設我們在redis的主節點上添加了一把分布式鎖,不幸的是主節點掛掉了,而且主節點上的鎖還沒有同步到從節點上,如果此時有客戶端來請求獲得同一把鎖,那么它將順利地獲得鎖,之前那把鎖會被無情地忽視掉,這就是分布式鎖在Redis集群中遇到的麻煩。
為了解決這個問題,Redis的作者提出了Redlock的算法來解決這個問題,推薦大家直接使用這個開源項目:https://github.com/samcook/RedLock.net
那么,順利解決了以上四個問題之后,我們的系統架構就演變成以下這個樣子。
歡迎大家掃描下方二維碼獲取我的最新原創文章: