早期的網站為了節省成本一般會設計成集中式系統,應用程序、數據庫等都部署在一臺服務器上。 但隨著業務的快速度發展,逐漸出現瓶頸,按一定原則**(應用拆分、服務拆分、數據拆分、應用解耦)**,向分佈式系統轉型,涉及到以下環節改造。
主要環節
- 業務拆分:將整個網站業務拆分成不同的應用,每個應用獨立部署維護,應用之間通過RPC或消息隊列通信。
- 集群化(應用服務器;基於RPC的微服務應用等)
- LVS負載均衡,負責將請求轉發給不同業務集群
- 反向代理服務器,常用的如Nginx
- 應用服務器,servlet容器,如tomcat
- 應用和數據服務分離,分別部署在不同的服務器
- 後端應用合理分層,通常分為表現層或網關層、業務邏輯層、數據持久層
- 緩存。分為兩種:本地緩存;分佈式緩存
- CDN化。靜態內容部署到CDN,就近獲取,加速網站響應。
- 數據庫讀寫分離。數據庫採用主從熱備,應用服務器在寫數據時訪問主數據庫,主數據庫通過主從複製機制將數據更新同步到從數據庫。
- 分庫分表,引入分佈式數據框架
- 引入NoSQL,支持海量數據存儲
- 藉助elastics search等開源搜索引擎
- 異步化,系統解耦。
- 縮短業務流程,加快網站訪問速度
- 消除併發訪問高峰
架構五要素:
- 高性能
- 可用性(Availability)
- 伸縮性(Scalability)
- 擴展性(Extensibility)
- 安全性
1、高性能
性能的測試指標主要有:
- 響應時間:指應用執行一個操作需要的時間
- 併發數:指系統能夠同時處理請求的數目
- QPS:指單位時間內系統處理的請求量
- 系統性能計數器:描述服務器或者操作系統性能的一些數據指標
性能優化,根據網站分層架構,可以分為三大類:
- Web 前端性能優化
- 減少 http 請求
- 使用瀏覽器緩存
- 啟用壓縮
- CSS 放在頁面最上面,JavaScript 放在頁面最下面
- 減少 Cookie 傳輸
- 應用服務器性能優化:主要手段有 緩存、集群、異步
- 多線程(設計為無狀態,使用局部對象,併發訪問資源使用鎖)
- 資源複用(單例,對象池)
- 數據結構
- 異步操作(消息隊列,削峰作用)
- 多臺應用服務器組成一個集群共同對外服務,提高整體處理能力。
- 使用 CDN,將網站靜態內容分發至離用戶最近的網絡服務商機房,使用戶通過最短訪問路徑獲取數據。可以在網站機房部署反向代理服務器,緩存熱點文件,加快請求響應速度,減輕應用服務器負載壓力
- 應用服務器端,可以使用服務器本地緩存和分佈式緩存(網站性能優化第一定律:優化考慮使用緩存優化性能)
- 代碼層面,也可以通過使用多線程、改善內存管理等手段優化性能。
- 數據庫服務器端,索引、緩存、SQL 優化等性能優化手段
- NoSQL 數據庫通過優化數據模型、存儲結構、伸縮特性等
- 存儲服務器性能優化
- 機械硬盤 vs. 固態硬盤
- B+ 樹 vs. LSM 樹
- RAID vs. HDFS
2、高可用
高可用的網站架構:目的是保證服務器硬件故障時服務依然可用、數據依然保存並能夠被訪問,主要手段數據和服務的冗餘備份及失效轉移
- 高可用的應用:顯著特點是應用的無狀態性
- 通過負載均衡進行無狀態服務的失效轉移
- 應用服務器集群的 Session 管理
- 高可用的服務:無狀態的服務,可使用類似負載均衡的失效轉移策略,此外還有如下策略
- 超時設置
- 異步調用
- 服務降級
- 限流
- 高可用的數據:主要手段是數據備份和失效轉移機制
- 失效確認
- 訪問轉移
- 數據恢復
- 冷備:缺點是不能保證數據最終一致和數據可用性
- 熱備:分為異步熱備和同步熱備
- 數據一致性(Consisitency)
- 數據可用性(Availibility)
- 分區耐受性(Partition Tolerance)
- CAP 原理
- 數據備份
- 軟件質量保證
- 自動化測試
- 預發佈驗證
- 灰度發佈
- 網站實時監控
- 警報系統
- 自動優雅降級
- 用戶行為日誌採集(服務器端和客戶端)
- 服務器性能監控
- 監控數據採集
- 監控管理
3、伸縮性
大型網站需要面對大量用戶的高併發訪問和存儲海量數據,不可能只用一臺服務器就處理全部用戶請求,存儲全部數據。網站通過集群的方式將多臺服務器組成一個整體共同提供服務。所謂伸縮性是指通過不斷向集群中加入服務器的手段來緩解不斷上升的用戶併發訪問壓力和不斷增長的數據存儲需求。
衡量架構伸縮性的主要標準就是是否可以用多臺服務器構建集群,是否容易向集群中添加新的服務器。加入新的服務器後是否可以提供和原來的服務器無差別的服務。集群中可容納的總的服務器數量是否有限制。
對於應用服務器集群,只要服務器上不保存數據,所有服務器都是對等的,通過使用合適的負載均衡設備就可以向集群中不斷加入服務器。
對於緩存服務器集群,加入新的服務器可能會導致緩存路由失效,進而導致集群中大部分緩存數據都無法訪問。雖然緩存的數據可以通過數據庫重新預熱,但是如果應用已經嚴重依賴緩存,可能會導致整個網站崩潰。需要改進緩存路由算法保證緩存數據的可訪問性。
關係數據庫雖然支持數據複製,主從熱備等機制,但是很難做到大規模集群的可伸縮性,因此關係數據庫的集群伸縮性方案必須在數據庫之外實現,通過路由分區等手段將部署有多個數據庫的服務器組成一個集群。
至於大部分 NoSQL 數據庫產品,由於其先天就是為海量數據而生,因此其對伸縮性的支持通常都非常好,可以做到在較少運維參與的情況下實現集群規模的線性伸縮。
概括起來伸縮性的分為如下幾個方面:
- 應用服務器集群的伸縮性設計
- 輪詢(Round Robin, RR)
- 加權輪詢(Weighted Round Robin, WRR)
- 隨機(Random)
- 最少鏈接(Least Connections)
- 源地址散列(Source Hashing)
- DNS 域名解析負載均衡
- 反向代理負載均衡(在 HTTP 協議層面,應用層負載均衡)
- IP 負載均衡(在內核進程完成數據分發)
- 數據鏈路層負載均衡(數據鏈路層修改 mac 地址,三角傳輸模式,LVS)
- 分佈式緩存集群的伸縮性設計
- Memcached 客戶端(包括 API,路由算法,服務器列表,通信模塊)
- Memcached 服務器集群
- 分佈式緩存的一致性 Hash 算法(一致性 Hash 環,虛擬層)
- 數據存儲服務集群的伸縮性設計
- 關係數據庫集群的伸縮性設計
- NoSQL 數據庫的伸縮性設計
4、可擴展
系統架構設計層面的“開閉原則”,構建可擴展的網站架構
- 利用分佈式消息隊列降低耦合性
- 分佈式消息隊列
- 事件驅動架構(Event Driven Architecture)
- 利用分佈式服務打造可複用的業務平臺
- 分佈式服務框架設計(Thrift,Dubbo)
- 可擴展的數據結構(如 HBase的 ColumnFamily 設計)
- 利用開放平臺建設網站生態圈
5、網站的安全架構
XSS 攻擊和 SQL 注入攻擊是構成網站應用攻擊最主要的兩種手段,此外還包括 CSRF,Session 劫持等手段。
- 攻擊與防禦
- Error Code
- 表單 Token
- 驗證碼
- jsonp請求的,Referer 校驗
- SQL 注入
- html 危險字符轉義
- XSS 攻擊:跨站點腳本攻擊(Cross Site Script)
對js轉義,使其失去執行功能,只作為純字符串展示
- CSRF 攻擊:跨站點請求偽造(Cross Site Request Forgery)
防範:httpOnly;增加token校驗;通過Referer識別。
- 網站安全漏洞掃描
閱讀更多 JAVA架構 的文章