架構中五個重要的核心指標,分別是性能、可用性、伸縮性、擴展性和安全性這5個架構指標
一、性能
性能就是核心要素之一,不然我為什么架構設計?隨隨便便一個lowlow的系統(tǒng)上線就好了。所以性能優(yōu)化是很多小公司賣不去過的坎。這么說吧,當然優(yōu)化網站性能的手段也非常多:
(1)web前端性能優(yōu)化:
1. 瀏覽器訪問優(yōu)化(瀏覽器緩存、頁面壓縮傳輸、合理布局頁面、減少Cookie傳輸)
· 減少http請求。避免建立太多通訊鏈路。將js、css、圖片文件盡可能合并。避免太多請求。同時,對于系統(tǒng)的后端請求也盡可能進行合理的設計,來避免出現(xiàn)太多交互。
·
· 使用瀏覽器的緩存。http頭設置Cache-Control和Expires.js文件名比如可以帶時間戳。一旦有更新則更新時間戳,否則緩存;同時盡量避免同一時間更新大量靜態(tài)資源。
· 對靜態(tài)資源進行壓縮。
· css放置在頁面最上方,js放下最下面。以提前進行css渲染。同時避免js帶來的頁面阻塞。但需要case by case。比如頁面dom節(jié)點需要依賴js生成,則可視情況改變文件位置。
· 減少cookie傳輸。同時讓靜態(tài)資源有獨立域名,發(fā)送靜態(tài)資源請求時候不發(fā)送cookie。以此減少傳輸代價。cookie可以通過document.cookie獲取。
2.CDN加速
· 緩存圖片、文件、CSS以及script腳本。但是pc上的CDN加速效果要好于移動端。經過調研發(fā)現(xiàn),last-mile的延遲越高,CDN的相對有效性越差(具體見文章為什么CDN對移動客戶端加速"沒有"效果)。
3.反向代理
· 可以提供七層負載均衡(http請求進行均衡策略),并且可以提供靜態(tài)資源的緩存,請求轉發(fā),防止網絡攻擊等。比較流行的有Nginx。
(2)應用服務器性能優(yōu)化:
如果請求靜態(tài)界面不卡了,但是動態(tài)數據還是卡,說明MySQL處理的請求太多了,可以使用服務器本地緩存和分布式緩存,也可以通過異步操作方式來加快響應,在高并發(fā)請求的情況下,可以將多臺應用服務器組成一個集群共同對外服務,提高整體處理能力,改善性能,具體如下:
1.分布式緩存(網站性能優(yōu)化的第一定律:優(yōu)先考慮使用緩存優(yōu)化性能)
1. 一般來說,存入cache的數據的讀寫比在2:1以上;且應該是熱點數據。
2. 需要考慮如果采用緩存則可能帶來的數據短期內的不一致,或者如果實時更新緩存可能帶來的性能和資源開銷。
3. 需要考慮cache一旦失效,大量請求直接命中DB可能帶來的服務性能雪崩。所以可以對cache采用集群化部署,以此避免丟失過多數據造成服務壓力陡增。
4. 對于熱點數據考慮進行緩存的預熱加載。比如高峰期來臨前,先將熱點數據提前存入緩存。以此提高高峰期的服務性能。
5. 為了避免惡意攻擊,一直query不存在的數據,導致cache無法命中而頻繁訪問DB,可以將不存在的數據也進行緩存并定期清理。同時有機制對惡意請求進行識別和封禁。
6. 分布式緩存應該去中心化并集中管理。通過不同實例間的互不通信和同構來保證可擴展性,并降低系統(tǒng)復雜度。
2.異步化(任何可以晚點做的事情都應該晚點再做,感覺像懶加載)
通過分布式消息隊列來實現(xiàn)削峰的目的。通過業(yè)務配合技術來解決問題。比如12306的排隊。
3.集群
采用集群也是服務虛擬化的一個體現(xiàn)。用以避免單點問題,同時提供更加高可用,高性能的服務。
4.代碼優(yōu)化
1. 多線程中,如果是密集型計算,線程數不宜超過CPU核數。如果是IO處理,則線程數=[任務執(zhí)行時間/(任務執(zhí)行時間-IO等待時間)] * CPU核數。除此之外,我們應該將對象設計成無狀態(tài)對象,多采用局部對象,適當將鎖細化。
2. 進行資源復用。比如采用單例模式,比如采用連接池。
3. 合理設置JVM參數,以最大程度避免不合理的full gc。
5.存儲性能優(yōu)化
關系型數據庫的索引采用B+樹進行實現(xiàn)。而很多的nosql數據庫則采用了LSM樹進行存儲。LSM在內存中保留最新增刪改查的數據,直到內存無法放下,則與磁盤的下一級LSM樹進行merge。所以對于寫操作較多,而讀操作更多的是查詢最近寫入數據的場景,其性能遠高于b+樹;采用HDFS結合map reduce進行海量數據存儲和分析。其能自動進行并發(fā)訪問和冗余備份,具有很高的可靠性。其等于是實現(xiàn)了RAID的功能。
(3)數據庫層優(yōu)化:
1. 數據庫層其實是最脆弱的一層,一般在應用設計時在上游就需要把請求攔截掉,數據庫層只承擔"能力范圍內"的訪問請求,所以,我們通過在服務層引入隊列和緩存,讓最底層的數據庫高枕無憂。但是如果請求激增,還是有大量的查詢壓力到MySQL,這個時候就要想辦法解決MySQL的瓶頸了,這時候可用使用索引、緩存、SQL性能優(yōu)化等手段,還可以使用NoSQL數據庫來優(yōu)化數據模型、存儲結構等。詳細內容可關注后查看我的【mysql優(yōu)化專題】,共12篇,已完結。
(4)衡量網站性能的指標(重要的有響應時間、TPS、系統(tǒng)性能計數器等,通過這些指標以確定系統(tǒng)設計是否達到目標)
1. 響應時間。
2. 并發(fā)數。如果暫時沒有對應的準確監(jiān)控,針對不同業(yè)務模型,可以有不一樣的并發(fā)數的預估。我們的系統(tǒng)進行峰值并發(fā)數預估的話,有一種比較粗略的計算方式,即全天請求平均每秒并發(fā)數 * 3。但也需要case by case。
3. 吞吐量。比較常見的有QPS(每秒查詢數)、HPS(每秒http請求數)以及TPS(每秒處理事務數)。
4. 性能計數器。包括系統(tǒng)負載、線程數、cpu、內存使用情況等。可以用top、free、cat /proc/cpuinfo等命令來查看。系統(tǒng)負載的定義為當前被CPU執(zhí)行的線程數/等待被CPU執(zhí)行的總線程數。當其值與邏輯cpu個數相同時是最佳狀態(tài),其代表所有的資源都被最大限度地被利用。但也有人認為當負載為0.7倍邏輯CPU數時最佳。
(5)高可用:包括高可用的應用、高可用的服務、高可用的數據和服務于高可用的監(jiān)控等,關于高可用,我還是決定開個單章講解
SochiOlympics
二、安全性
互聯(lián)網是開放的,任何人在任何地方都可以訪問網站。網站的安全架構就是保護網站不受惡意訪問和攻擊,保護網站的重要數據不被竊取。
安全的5個要素:機密性、完整性、可用性、可控性和可審查性。
1、安全系統(tǒng)架構
1)安全服務是指計算機網絡提供的安全防護措施,包括認證服務、訪問控制、數據機密性服務、數據完整性服務和不可否認服務。
2)特定的安全機制是用來實施安全服務的機制,包括加密機制、數據簽名機制、訪問控制機制、數據完整性機制、認證交換機制、流量填充機制、路由控制機制和公證機制。
3)普遍性的安全機制不是為任何特定的服務而特設的,屬于安全管理方面,分為可信功能度、安全標記、事件檢測、安全審計跟蹤和安全恢復。
2、安全保護等級
1)用戶自主保護級
2)系統(tǒng)審計保護級
3)安全標記保護級
4)結構化保護級
5)訪問驗證保護級
衡量網站安全架構的標準就是針對現(xiàn)存和潛在的各種攻擊和竊密手段,是否有可靠的應對策略。
三、可用性
衡量一個系統(tǒng)架構設計是否滿足高可用的目標,就是假設系統(tǒng)中任何一臺或者多臺服務器宕機時,以及出現(xiàn)各種不可預期的問題時,系統(tǒng)整體是否依然可用。
一般就三個手段、冗余、集群化、分布式。
網站高可用的主要手段就是冗余,應用部署在多臺服務器上同時提供服務,數據存儲在多臺服務器上相互備份,任何一臺服務器都不會影響應用的整體可以,通常的實現(xiàn)手段即把多臺服務器通過負載均衡設備組成一個集群。
四、擴展性
擴展性(Extensibility)指對現(xiàn)有系統(tǒng)影響最小的情況下,系統(tǒng)功能可持續(xù)擴展或提升的能力。表現(xiàn)在系統(tǒng)基礎設施穩(wěn)定不需要經常變更,應用之間較少依賴和耦合,當系統(tǒng)增加新功能時,不需要對現(xiàn)有系統(tǒng)的結構和代碼進行修改。這個沒啥好說。擴展性依賴于前期良好的架構設計。合理業(yè)務邏輯抽象,水平/垂直切割分布式化等等。
網站可擴展架構的主要手段是事件驅動架構和分布式服務。
事件驅動通常利用消息隊列實現(xiàn),通過這種方式將消息生產和處理邏輯分隔開。
服務器服務則是將業(yè)務和可復用服務分離開來,通過分布式服務框架調用。新增加產品可用通過調用可復用的服務來實現(xiàn)自身的業(yè)務邏輯,而對現(xiàn)有產品沒有任何影響。
對此,《可擴展的藝術》一書提出了一個更加系統(tǒng)的可擴展模型—— AKF可擴展立方 (Scalability Cube)。這個立方體中沿著三個坐標軸設置分別為:X、Y、Z。
· X軸擴展 —— 關注水平的數據和服務克隆,也就是前文提到的"加機器解決問題"
· Y軸擴展 —— 關注應用中職責的劃分,比如數據類型,交易執(zhí)行類型的劃分
· Z軸擴展 —— 關注服務和數據的優(yōu)先級劃分,如分地域劃分
整個擴展模型,用下圖來表示,其中原點代表完全無擴展的狀態(tài)。
五、伸縮性
服務盡量同構。DB、cache在考慮分布式時盡量提前設計好擴展方案。也可以采用一些主流的對水平伸縮支持較好的nosql、memcached、hbase等。
(1)橫向分離:將不同的業(yè)務模塊分離部署,實現(xiàn)系統(tǒng)的伸縮性;
(2)縱向分離:將業(yè)務處理流程上得不同部分分離部署,實現(xiàn)系統(tǒng)的伸縮性;