什么是軟件架構
維基百科定義: 軟件架構是指有關軟件整體結構與組件的抽象描述,用于指導大型軟件系統各個方面的設計 。
軟件架構5大要素:

- 性能
- 可用性
- 伸縮性
- 擴展性
- 安全性
可以通過考察這5大要素來衡量一個軟件架構設計的優劣。
高性能
網站性能是客觀的指標,具體體現到 響應時間 、 吞吐量 等技術指標。
性能優化的最終目的: 改善用戶體驗 。
網站性能測試是性能優化的前提和基礎,也是性能優化結果的檢查和度量標準。
下面從三個視角來看看網站性能的不同標準:
用戶視角
網站響應速度快慢(通信時間,處理時間、解析響應數據的時間)。
開發人員視角
關注程序本身及其相關子系統的性能,包括響應延遲、系統吞吐量、并發處理能力、系統穩定性等技術指標。
運維人員視角
關注基礎設施性能和資源利用率,如網絡運營商的帶寬能力、服務器硬件配置、數據中心網絡架構、服務器和網路帶寬的資源利用率等。
性能測試指標
網站性能測試的主要指標主要有:
- 響應時間:應用執行一個操作需要的時間(從發出請求開始到收到最后響應數據所需要的時間)。
- 并發數:系統能夠同時處理請求的數目,反映了系統的負載特性。。
- 吞吐量:單位時間內系統處理的請求數量,體現系統的整體處理能力。存在一個極限值。
- TPS:每秒事務數
- HPS:每秒HTTP請求數
- QPS:每秒查詢數
- 性能計數器:描述服務器或操作系統的一些數據指標。主要包括:
- System Load:系統負載,指當前正在被CPU執行和等待被CPU執行的進程數目總和(反映系統忙閑程度的重要指標)。
- 對象與線程數
- 內存使用
- CPU使用
- 磁盤與網絡I/O
性能測試方法
性能測試是一個不斷對系統增加訪問壓力,以 獲得系統性能指標、最大負載能力、最大壓力承受能力的過程。性能測試主要包括以下幾種方法:
- 性能測試:對系統不斷施壓,驗證系統在資源可以接受范圍內,是否能達到預期。
- 負載測試:對系統不斷增加并發請求,直到系統的某項或多項性能指標達到安全臨界值。
- 壓力測試:在超過安全負載的情況下,對系統繼續施壓,直到系統崩潰或不能再處理請求,已獲得系統最大承受能力。
- 穩定性測試:系統在特定的硬件、軟件、網路環境條件下,給系統加載一定壓力,使系統運行一段較長時間,以檢查系統是否穩定。
性能分析與優化
排查網站的性能瓶頸的方法:檢查請求處理的各個環節的日志,分析哪個環節響應時間不合理、超過預期;然后檢查監控數據,分析影響性能的主要因素是內存、磁盤、網絡還是 CPU,時代嗎問題還是架構設置不合理,或者系統資源確實不足。
定位到了性能具體問題后,然后根據性能產生的原因進行性能優化。性能優化主要從三個方面進行優化:
- Web前端性能優化
- 應用服務器性能優化
- 存儲服務器性能優化
性能優化策略
Web前端優化
1. 瀏覽器訪問優化
- 減少HTTP請求:分別合并css、JS、圖片等資源,減少瀏覽器的請求次數。
- 使用瀏覽器緩存:瀏覽器將CSS、JS、圖標等靜態資源緩存在瀏覽器中,那樣就不用每次都去請求服務器,可以極好地改善性能。設置HTTP頭中 Cache-Control 和 Expires 屬性。
- 啟用壓縮:在服務器端對文件進行壓縮,在瀏覽器端對文件進行解壓,可有效減少通信傳輸的數據量。壓縮比80%以上。壓縮和解壓縮會消耗服務器和瀏覽器所在的系統的CPU資源。
- CSS放在頁面最上面,JS放在頁面最下面:加載JS后會立即執行,可能會阻塞頁面渲染。
- 減少Cookie傳輸:減少Cookie中傳輸的數據量,請求靜態資源沒有必要發送Cookie。
2. CDN加速
CDN(Content Distribute Network,內容分發網絡),是指將數據緩存在離用戶最近的地方,使用戶以最快的速度獲取數據,提升網頁的打開速度。
CDN適合緩存 靜態資源 ,如圖片、文件、CSS、腳本、靜態文件等。
3. 反向代理
反向代理是指服務器根據客戶端的請求,從其關聯的一組或多組后端服務器上獲取資源,然后再將這些資源返回給客戶端,客戶端只會得知反向代理的IP地址,而不知道在代理服務器后面具體的真實服務器的存在。
反向代理的作用:
- 安全功能
- 通過緩存配置加速Web請求(靜態資源)
- 負載均衡,通過構建集群,提高系統總體處理能力
應用服務器優化
1. 分布式緩存
網站性能優化第一定律: 優先考慮使用緩存優化性能 。
原理:將數據存儲在訪問速度較高的存儲介質中,加快訪問速度。
緩存作用:
- 緩存訪問速度快,減少數據訪問時間
- 緩存計算結果,節省計算的時間
合理使用緩存:
- 緩存讀寫比高,變化少的數據
- 盡量緩存熱點數據
- 確保數據有效性,根據業務場景,選擇是否能容忍數據一定時間內不一致,還是及時更新
- 對緩存設置失效時間,緩存數據丟失或者不可用,會從數據庫直接獲取數據
- 緩存預熱:在緩存啟動的時候就把熱點數據加載好。
- 避免緩存穿透:將不存的數據也緩存起來。
2. 異步操作
使用消息隊列將調用異步化,以改善網站的性能。
使用消息隊列后,用戶請求的數據發送給消息隊列后就立即返回,再由消息隊列的消費者從消息隊列中獲取數據,再進行邏輯處理(如寫入數據庫)。
3. 使用集群
使用負載均衡技術為應用構建一個由多臺服務器組成的服務器集群,將并發訪問請求分發到多臺服務器上處理,避免單一服務器因負載壓力過大而響應緩存,降低用戶請求響應延遲,提升用戶體驗。
4. 代碼優化
代碼優化主要關注以下幾個方面:
- 多線程:涉及線程安全問題,多線程并發對某個資源進行修改,解決辦法:
- 將對象設計為無狀態對象
- 使用局部對象
- 并發訪問資源時使用鎖
- 資源復用:減少開銷較大的系統資源的創建和銷毀,如數據庫連接、網絡通信連接、線程、復雜對象等。
- 單例(Singleton)
- 對象池(Object Pool)
- 數據結構
- 垃圾回收
存儲性能優化
磁盤是系統最嚴重的瓶頸。
1. 機械硬盤 & 固態硬盤
在網站應用中,大部分應用訪問數據都是隨機的,機械硬盤由于需要移動磁頭臂,所以性能較差。SSD具有更好的性能。
2. B+樹 & LSM樹
為了改善數據訪問特性,文件系統或數據庫系統通常會對數據排序后存儲,以加快檢索速度,這樣就需要保證數據在不斷更新、插入、刪除后依然有序。
傳統關系數據庫使用B+樹,B+樹是一種專門針對磁盤而優化的N叉排序樹,以樹節點為單位存儲在磁盤中,從根開始查找所需數據所在的節點編號和磁盤位置,將其加載到內存中然后繼續查找,直到找到所需的數據。
LSM樹是一個N階合并樹。數據的插入、修改和刪除都是在內存中進行,并且都會創建一個新記錄,這些數據在內存中以樹結構排序,當數據量超過設定的閾值后,會和磁盤上最新的的排序樹合并。在合并的過程中,會用最新更新的數據覆蓋舊的數據。讀操作先從內存中排序樹開始搜索,如未找到,再從磁盤上排序樹順序查找。
在LSM樹上進行一次數據更新不需要磁盤訪問,在內存即可完成,速度遠快于B+樹。
對于寫多,集中讀最近寫入數據的場景,使用LSM樹可以極大的減少磁盤的訪問次數,加快訪問速度。
3. RAID & HDFS
RAID
廉價磁盤冗余陣列,主要是為了改善磁盤的訪問延遲,增強磁盤的可用性和容錯能力。
多塊磁盤通過使用RAID技術,實現數據在多塊磁盤上的并發讀寫和數據備份。
常用RAID技術:
- RAID0:在寫的時候,根據磁盤數量將數據分成N份,并發寫入N塊磁盤。在讀的時候,從N塊磁盤上并發讀。RAID0具有極快的數據讀取速度,但是未做備份。
- RAID1:數據寫入的時候,將一份數據同時寫入兩塊磁盤,一塊磁盤損壞不會導致數據丟失,插入新磁盤可以通過復制數據方式自動修復,可靠性高。
- RAID10:將所有磁盤平均分成兩份,數據同時在兩份磁盤寫入,結合RAID0和RAID1兩種方案,既提高了可靠性又改善了性能,但是RAID10的磁盤利用率較低,一般磁盤用來備份數據。
- RAID3:數據寫入的時候,將數據分成N-1份,并發寫入N-1塊磁盤,并在第N塊磁盤記錄校驗數據,任何一塊磁盤損壞(包括校驗數據磁盤),都可以利用其它N-1塊磁盤的數據修復。在數據修改較多的場景,會導致第N塊磁盤頻繁重寫校驗數據,容易造成磁盤損壞,所以一般少在實踐中使用。
- RAID5:與RAID3類似,但是校驗數據是螺旋寫入所有磁盤,避免頻繁寫一塊盤。
- RAID6:與RAID5類似,數據值寫入N-2塊磁盤,螺旋式地在兩塊磁盤中寫入校驗信息(不同算法),數據可靠性最高。
HDFS
系統在整個存儲集群的多臺服務器上進行數據并發讀寫和備份。HDFS以塊(Block)為單位管理文件內容,一個文件被切分成多個Block,當應用程序寫文件時,每寫完一個Block,HDFS會將其自動復制到另外兩臺機器上,保證3副本(默認)。在處理文件的時候(MapReduce),可以同時啟動多個任務并行讀取文件的不同Block,并發處理,提升讀取效率。
HDFS配置MapReduce等并行計算框架進行大數據處理時,可以在整個集群上并發讀寫訪問所有的磁盤安,無需RAID支持。
高可用
網站的可用性描述 網站可有效訪問 的特性。
可用性度量:服務7*24可用,可用性超過99.99%。
網站不可用時間(故障時間) = 故障修復時間點 - 故障發現(報告)時間點 網站年度可用性指標=(1-網站不可用時間/年度總時間)*100%
硬件故障是常態,網站的高可用架構設計主要目的: 保證服務器硬件故障時服務依然可用、數據依然能保存并能被訪問 。
高可用架構的主要手段:數據和服務 冗余備份 及 失效轉移 。
一個典型的網站設計通常遵循三層架構模型:
- 應用層:負責具體業務邏輯處理
- 服務層:負責提供可復用的服務
- 數據層:負責數據的存儲于訪問
高可用的應用
應用的顯著特點:無狀態性。
無狀態應用是指應用服務器不保存業務的上下文信息,僅根據每次請求提交的數據進行相應的業務邏輯處理。多個服務器實力之間完全對等,請求提交到任意服務器,處理結果都是完全一樣的。
通過負載均衡進行無狀態服務的失效轉移
通過負載均衡手段,將流量和數據均勻分配到一個集群組成的多臺服務器上,以提高系統的整體負載處理能力。
應用服務器集群的Session管理
Session管理手段:
1. Session復制應用服務器開啟Web容器的Session復制功能,在集群中的幾臺服務器之間同步Session對象,使得每臺服務器上都保存所有用戶的Session信息,這樣任何一臺機器宕機都不會導致Session數據的丟失。適合小規模集群。當集群比較大時,集群服務器間需要大量的通信進行Session復制,會占用大量服務器和網絡資源。
2. Session綁定利用負載均衡的源地址Hash算法實現,負載均衡服務器總是將來源于同一IP的請求分發到同一臺服務器上,也可以根據Cookie信息將同一個用戶的請求總是分發到同一臺機器上,這樣在整個會話期間沒用戶所有的請求都在同一臺服務器上處理,即Session綁定在某臺特定服務器上,又稱 會話黏滯 。
缺點:不符合對系統高可用的需求,某臺服務器宕機,那么該機器上的Session會丟失。很少使用。
3. 利用Cookie記錄Session
利用瀏覽器支持的Cookie記錄Session。每次請求的時候,將Session放在請求中發送到服務器,服務器處理完請求之后再將修改過的Session響應給客戶端。
缺點:受Cookie大小限制,記錄信息有限;每次請求都需傳輸Cookie,影響性能;如用戶關閉Cookie,訪問就會異常。
4. Session服務器
利用獨立部署的Session服務器集群統一管理Session,應用服務器每次讀寫Session時,都訪問Session服務器。
將應用服務器的狀態分離,分為無狀態的應用服務器和有狀態的Session服務器,針對這兩種服務器的不同特性分別設計其架構。
Session服務器實現:分布式緩存、數據庫等。
高可用的服務
高可用的服務模塊為業務產品提供 基礎公共服務 ,一般是 獨立部署 。
高可用的服務策略:
1. 負載均衡
通過負載均衡的失效轉移策略實現高可用。
2. 分級管理
根據應用和服務的重要程度進行分級管理,不同重要程序的服務使用不同的硬件資源,越重要的的服務使用越好的硬件資源。核心服務和數據部署在不同地域的數據中心。
3. 超時設置
設置服務調用的超時時間,一旦超時,通信框架拋出異常,應用程序根據服務調度策略,選擇繼續重試或將請求轉移到相同服務的其他服務器上。
4. 異步調用
應用對服務的調用通過消息隊列等異步方式完成,避免一個服務失敗導致整個應用請求失敗。
5. 服務降級
網站訪問高峰期,服務可能因為大量的并發調用而性能下降,嚴重時可能會導致服務宕機。為了保證核心應用和功能的正常運行,對服務進行降級。
降級手段:
- 拒絕服務:拒絕低優先級應用的調用,減少服務調用并發數,確保核心應用正常使用;或隨機拒絕部分請求調用,節約資源。
- 關閉服務:關閉部分不重要的服務,或者服務內部關閉部分不重要的功能,節約系統開銷,重要功能讓出資源。
6. 冪等性設計
服務層必須保證重復調用和調用一次產生的結果相同,即服務具有冪等性。
高可用的數據
1. CAP
為了保證數據的高可用,會犧牲 數據一致性 。
高可用的數據含義:
- 數據持久性:保證數據持久存儲,不會出現數據丟失的問題。
- 數據可訪問性:在多份數據副本分別存放在不同存儲設備的情況下,一個數據存儲設備損壞需要將數據訪問切換到其他數據存儲設備上。
- 數據一致性:多副本之間數據一致。
CAP原理:一個提供數據服務的存儲系統無法同時滿足 數據一致性(Consistency) 、 數據可用性(Availibility) 、**分區耐受性(Partition Tolerance,系統具有跨網絡分區的伸縮性)**這三個條件。
在大型網站應用中,數據規模總是快速擴張的,因此可伸縮即分區耐受性必不可少,規模變大以后,機器數量也會變得龐大,這是網路和服務器故障會頻繁吹安,要想保證應用可用,就必須保證分布式處理系統的高可用。所以在大型網站中,通常會選擇強化分布式存儲系統的可用性(A)和伸縮性(P),而在某種程度上放棄一致性(C)。
數據不一致出現原因:系統高并發寫操作或者集群狀態不穩定(故障恢復、集群擴容)。
數據一致性分為:
- 數據強一致:各副本的數據在物理存儲中總是一致的;數據更新操作結果和操作響應總是一致的,即操作響應通知更新失敗,那么數據一定沒有被更新,而不是出于不確定狀態。
- 用戶數據一致:數據在物理存儲中的各個副本的數據可能是不一致的,但終端用戶訪問時,通過糾錯和校驗機制,可以確定一個一直的且正確的數據返回給用戶。
- 數據最終一致:物理存儲的數據可能不一致,終端用戶訪問到數據可能不一致,但系統經過一段時間的自我恢復和修正,數據最終達到一直。
保證數據存儲高可用的手段:
2. 數據備份
保證數據有多個副本,任意副本的失效都不會導致數據的永久丟失,從而實現數據完全的持久化。
數據備份方式:
- 冷備:簡單、廉價、成本和技術難度低。缺點不能保證數據最終一致。
- 熱備:
- 異步熱備:多份數據副本的寫入操作異步完成。
- 同步熱備:多份數據副本的下入操作同步完成。
3. 失效轉移機制
保證當一個數據副本不可訪問時,可以快速切換訪問數據的其他副本,保證系統可用。
失效轉移操作組成:
- 失效確認:通過 心跳檢測 和 應用程序訪問失敗報告 判斷服務器是否宕機
- 訪問轉移:將數據的讀寫訪問重新路由到其他服務器(不路由到宕機的服務器)
- 數據恢復:從健康的服務器復制數據,將數據副本數目恢復到設定值
高可用網站的軟件質量保證
為了保證線上系統的可用性采取的一些質量保證手段:
- 網站發布:每次關閉服務器中的一小部分,并在發布完成后立即可以訪問。
- 自動化測試:Selenium自動化測試工具。
- 預發布驗證:先發布到預發布機器上,然后進行預發布驗證,驗證典型的業務流程,確認沒有問題后正式發布。
- 代碼控制:主干開發、分支發布;分支開發,主干發布。工具:SVN,Git。
- 自動化發布:火車發布模型。
- 灰度發布:將集群服務器分成若干部分,每天只發布一部分服務器,觀察運行是否穩定,第二天繼續發布一部分服務器。
網站運行監控
監控數據采集
- 用戶行為日志收集
- 服務器端日志收集
- 客戶端瀏覽器日志收集
- 服務器性能監控
- 系統Load
- 內存占用
- 磁盤
- 網絡IO
- 運行數據報告:監控一些與具體業務場景相關的技術和業務指標。
監控管理
需要根據實時監控數據進行風險預警,并對服務器進行失效轉移,自動負載調整,最大化利用集群所有機器資源。
- 系統報警:對超過閾值的指標進行報警,如郵件、短信、語音等。
- 失效轉移:發現故障主動通知應用,進行失效轉移。
- 自動優雅降級:為應對訪問高峰,主動關閉部分功能,釋放部分系統資源,保證網站核心功能正常訪問。
可伸縮
伸縮性是指通過不斷向集群中加入服務器的手段來緩解不斷上升的用戶并發訪問壓力和不斷增長大數據存儲需求。
衡量架構伸縮性標準:
- 是否可以用多臺服務器構建集群
- 是否容易向集群中添加新的服務器
- 加入新的服務器后是否可以提供和原來的服務無差別的服務
- 集群中可容納的服務器數量是否有限制
網站的伸縮性設計分類
網站的伸縮性設計主要分成以下兩類:
1. 根據功能進行物理分離實現伸縮
通過物理上分離不同的網站功能,實現網站伸縮性的手段,可以在網站發展的任何階段使用。不同服務器部署不同的服務,提供不同的功能。
分離主要分為兩種情況:
- 縱向分離(分層后分離):將業務處理流程上的不同部分分離部署,實現系統伸縮性。
- 橫向分離(業務分割后分離):將不同的業務模塊分離部署,實現系統伸縮性。
2. 單一功能通過集群實現伸縮
隨著網站訪問量的逐步增加,單一的服務器也不同滿足業務規模的要求,需要使用服務器集群,將相同服務部署在多臺服務器上構成一個集群整體對外提供服務。
應用服務器集群的伸縮性設計
負載均衡技術
1. HTTP重定向負載均衡
利用HTTP重定向協議實現負載均衡。
HTTP重定向服務器會根據用戶的HTTP請求計算一臺真實的Web服務器地址,并將該Web服務器地址寫入HTTP重定向響應(響應狀態碼302)中返回給用戶瀏覽器,瀏覽器自動重新請求實際物理服務器。
優缺點:
- 優點:實現簡單
- 缺點:瀏覽器需要兩次請求服務器才能完成一次訪問,性能較差;重定向服務器自身處理能力會成為瓶頸;使用302重定向,可能會讓搜索引擎判斷為seo作弊,降低搜索排名。
HTTP重定向負載均衡在實際生產環境中很少使用。
2. DNS域名解析負載均衡
通過DNS處理域名解析請求的同時進行負載均衡處理的一種方案。
每次域名解析請求都會根據負載均衡算法計算一個不同的IP地址返回,可以將請求分布到多臺服務器上,實現負載均衡。
優缺點:
- 優點:將負載均衡的工作轉交給DNS,省去了網站管理維護負載服務器的麻煩;DNS還支持基于地理位置的域名解析,會將域名解析成距離用戶地理最近的一個服務器地址,從而加快用戶訪問速度,改善性能。
- 缺點:DNS是多級解析,每級DNS都會緩存服務器配置,修改了DNS配置,需要較長時間才能生效。
DNS域名解析一般作為第一級負載均衡。
3. 反向代理負載均衡
利用反向代理服務器進行負載均衡。
優缺點:
- 優點:和代理服務器集成簡單
- 缺點:反向代理服務器是所有請求和響應的中轉站,其性能可能會成為瓶頸。
4. IP負載均衡
在網絡層通過修改請求目標地址進行負載均衡。在內核進程中完成數據分發,性能較好。集群的最大響應數據吞吐量受制于負載均衡服務器網卡帶寬。
5. 數據鏈路層負載均衡
在通信協議的數據鏈路層修改mac地址進行負載均衡。linux平臺最好的鏈路層負載均衡開源產品 LVS 。
負載均衡算法
1. 輪詢(Round Robin,RR)
所有請求被依次分發到每臺應用服務器上,即每臺服務器需要處理的請求數目都相同,適合于所有服務器硬件都相同的場景。
2. 加權輪詢(Weight Round Robin,WRR)
根據應用服務器硬件性能的情況,在輪詢的基礎上,按照配置的權重將請求分發到每個服務器,性能高的服務器分配更多請求。
3. 隨機(Random)
請求被隨機分配到各個應用服務器。實現簡單。
4. 最少連接(Least Connections)
記錄每個應用服務器正在處理的連接數(請求數),將新到的請求分發到最少連接的服務器上。最符合負載均衡定義的算法。
5. 源地址散列(Source Hashing)
根據請求來源IP地址進行Hash計算,得到應用服務器,這樣來自同一個IP地址的請求總在同一個服務器上處理,該請求的上下文信息可以存儲在這臺服務器上,在一個會話內重復使用,從而實現會話黏滯。
分布式緩存集群的伸縮性設計
分布式緩存服務器集群中不同服務器中緩存的數據各不相同,緩存訪問請求不可以在緩存服務器集群中的任意一臺處理,必須先找到緩存有需要數據的服務器,然后才能訪問。
緩存的目的: 加速數據讀取的速度 并 減輕數據存儲服務器的負載壓力 。
分布式緩存集群伸縮性設計的主要目標:新加入緩存服務器應使整個緩存服務器集群中已經緩存的數據盡可能還被訪問到。
一致性哈希算法
一致性Hash算法通過一致性Hash環的數據結構實現Key到緩存服務器的Hash映射。
算法過程:先構造一個長度為 0~的整數環(一致性Hash環),根據節點名稱的Hash值( 范圍0~)將緩存服務器節點放置在這個Hash環上。然后根據需要緩存的數據的Key值計算得到其Hash值,然后再Hash環上順時針找距離這個Key的Hash值(范圍 0~)最近的緩存服務節點,完成Key到服務器的Hash映射查找。
擴容的時候,將新加入的節點的Hash放入一致性Hash環中,由于Key是順時針查找距離最近的節點,因此新加入的節點只影響整個換中的一小段。
解決一致性Hash算法帶來的負載不均衡的問題
將每臺物理緩存服務器虛擬為一組虛擬緩存服務器,將虛擬服務器的Hash值放置在Hash環上,Key在換上先找到虛擬服務器節點,在得到物理服務器的信息。這樣新加入的物理服務器節點是一組虛擬節點,如果虛擬節點足夠多的,這組虛擬節點將會影響同樣多數目的已經在環上存在的虛擬節點。
物理節點對應的虛擬節點越多,各個物理節點之間的負載越均衡,新加入物理服務器對原有的物理服務器的影響越保持一致。
根據經驗,一臺物理服務器虛擬為150個虛擬服務器節點。
數據存儲服務器集群的伸縮性設計
數據存儲層必須保證數據的可靠存儲,任何情況下都必須保證數據的 可用性 和 正確性 。
1. 關系數據庫集群的伸縮性設計
架構設計:主從架構、主從讀寫分離、主從復制、分庫
分庫:不同業務數據表部署在不同的數據庫集群上。缺點:夸庫不能Join。
2. NoSQL數據庫的伸縮性設計
NoSQL數據庫產品都放棄了關鍵數據庫的兩大重要基礎:
- 以關系代數為基礎的結構化查詢語言(SQL)
- 事務一致性保證(ACID)
NoSQL更關注: 高可用性 和 可伸縮性
可擴展
軟件設計的終極目標: 低耦合 系統。
低耦合系統更容易擴展,低耦合模塊更容易復用,低耦合的系統設計會讓開發過程和維護變得更加輕松和容易管理。
主要目的:網站的架構能夠快速響應需求變化。
可擴展架構的核心思想: 模塊化,并在此基礎之上,降低模塊間的耦合性,提高模塊的復用性。
衡量標準:網站增加新的業務產品時,是否可以實現對現有產品透明無影響,不需要任何改動或者很少鈣能既有業務功能就可以上線新產品。不同產品之間低耦合。
網站可伸縮架構主要手段是 事件驅動架構 和 分布式服務 。
利用分布消息隊列降低系統耦合性
事件驅動架構
事件驅動架構(Event Driven Architecture):通過在低耦合的模塊之間傳輸事件消息,以保持模塊的松散耦合,并借助事件消息的通信完成模塊間合作。如生產者消費者模式。
常用的事件驅動架構:分布式消息隊列。
利用消息隊列,將用戶請求和其他業務事件構造成消息發布到消息隊列,消息的處理者作為消費者從消息隊列中獲取消息進行處理。通過這種方式將消息產生和消息處理分離開來,可以透明地增加新的消息生產者任務或者新的消息消費者任務。
分布式消息隊列
消息 生產者 應用程序通過遠程訪問接口將 消息 推送 給 消息隊列服務器 ,消息隊列服務器將消息寫入本地內存隊列后即立即返回成功響應給消息生產者。消息隊列服務器根據消息訂閱列表查找訂閱該消息的消息消費者應用程序,將消息隊列中的消息按照 先進先出 的原則將 消息通過遠程通信接口發送給消息 消費者 程序。
利用分布式服務打造可復用的業務平臺
將業務和可復用服務分離開來,通過分布式服務框架調用。
巨無霸應用存在問題:
- 編譯、部署困難
- 代碼分支管理困難
- 數據庫連接耗盡
- 新增業務困難
解決方案就是 拆分 ,將模塊獨立部署,降低系統耦合性。
- 縱向拆分:將一個大應用拆分為多個小應用,如果新增業務比較獨立,那么就直接將其部署為一個獨立的應用系統。
- 橫向拆分:將復用的業務拆分開來,獨立部署為分布式服務,新增業務只需調用這些分布式服務,不需要依賴具體的模塊代碼。
大型網站分布式服務的需求和特點
- 服務注冊與發現
- 服務調用
- 負載均衡
- 失效轉移
- 高效的遠程通信
- 整合異構系統
- 對應用最少侵入
- 版本管理
- 實時監控
利用開放平臺建設網站生態圈
- API接口:Restful、WebService、RPC等
- 協議轉換:將各種API輸入轉換成內部服務可以識別的形式,并將內部服務的返回封裝成API的格式。
- 安全:身份識別、權限控制、分級的訪問帶寬限制。
- 審計:記錄第三方應用的訪問情況,并進行監控、計費等。
- 路由:將開放平臺的耕種訪問路由映射到具體的內部服務。
- 流程:將一組離散的服務組織成一個上下文相關的新服務,隱藏服務細節,提供統一接口供開發者調用。
安全性
安全性是指保護網站不受惡意訪問和攻擊,保護網站的重要數據不被竊取。
衡量標準:針對現存和潛在的各種攻擊與竊密手段,是否有可靠的應對策略。
網站攻擊和防御
XSS攻擊
XSS攻擊即 跨站點腳本攻擊 (Cross Site Script),指黑客通過篡改網頁,注入惡意html腳本,在用戶瀏覽網頁時,控制用戶瀏覽器進行惡意操作的一種攻擊方式。常見攻擊類型有:
- 反射型:攻擊者誘使用戶點擊一個嵌入惡意腳本的連接,達到攻擊目的。
- 持久型:黑客提交含有惡意腳本的請求,保存在被攻擊的Web站點的數據庫中,用戶瀏覽網頁時,惡意腳本被包含在正常頁面中,達到攻擊的目的。
XSS防攻擊手段:
- 消毒:對html危險字符進行轉義。消毒幾乎是所有網站最必備的XSS防攻擊手段。
- HttpOnly:瀏覽器進制頁面JAVAScript訪問帶有HttpOnly屬性的Cookie。HttpOnly主要是防止XSS攻擊者竊取Cookie。
注入攻擊
注入攻擊主要由 SQL注入攻擊 和 OS注入攻擊 兩種。
SQL注入攻擊
攻擊者在HTTP請求中注入惡意SQL命令,服務器用請求參數構造數據庫SQL命令(如刪除數據庫表)時,惡意SQL被一起構造,并在數據庫中執行。
SQL注入攻擊前提:攻擊者需要對要攻擊的數據庫結構有所了解。
攻擊者獲取數據庫表結構信息手段:
- 開源:開源軟件搭建的網站數據結構是公開的。
- 錯誤回顯:攻擊者可以通過服務端返回的異常信息,猜測數據庫表結構。
- 盲注:攻擊者根據頁面變化情況判斷SQL語句的執行情況,猜測數據庫表結構。
防御
首先應避免被攻擊者猜測到表名等數據庫表結構信息。
除此之外還有以下兩種方式:
- 消毒:通過正則匹配過濾請求數據中可能注入的SQL。請求參數消毒是一種比較簡單粗暴又有效的手段。
- 參數綁定:使用預編譯手段,綁定參數是最好的防SQL注入方法。
CSRF攻擊
CSRF(Cross Site Request Forgery, 跨站點請求偽造 ),指的是攻擊者通過跨站請求,以合法用戶的身份進行非法操作,如轉賬交易、發表評論等。
CSRF攻擊的主要手法:利用跨站請求,在用戶不知情的情況下,以用戶的身份偽造請求。
核心是利用了瀏覽器Cookie或服務器Session策略,盜取用戶身份。
CSRF攻擊防御主要手段是 識別請求者身份 。主要有下面幾種方法:
- 表單Token:通過在請求參數中增加隨機數的方法來阻止攻擊者獲得所有請求參數。正常請求會包含token隨機數,每次請求都不一樣,偽造請求無法獲得該值,服務器檢查請求參數中token的值是否存在并且正確以確定請求提交者是否合法。
- 驗證碼:在請求提交時,需要用戶輸入驗證碼,以避免在用戶不知情的情況下被攻擊者偽造請求。但是輸入驗證碼是一個很糟糕的用戶體驗。
- Referer Check:通過檢查HTTP請求的Referer域中記錄的請求來源,驗證其是否合法。常見場景如:圖片防盜鏈。
其他攻擊和漏洞
1. Error Code
錯誤回顯,指的是服務器端未處理異常堆棧信息直接輸出到客戶端瀏覽器。
防御:配置web服務器參數,跳轉500頁面到指定的錯誤頁面,避免將異常堆棧信息直接返回給用戶。
2. HTML注釋
在瀏覽器中是可以看到HTML代碼中注釋的部分,這樣會給黑客造成攻擊便利。
防御:程序在最終發布前需要進行代碼review或自動掃描,避免HTML注釋漏洞。
3. 文件上傳
攻擊方式:上傳一個可執行的程序,并通過該程序獲得服務器端命令執行能力。
防御:設置上傳文件白名單,只允許上傳可靠的文件類型。此外還可以修改文件名、使用專門的存儲等手段,保護服務器免受上傳文件攻擊。
4. 路徑遍歷
攻擊方式:攻擊者在請求的URL中使用相對路徑,遍歷系統為開放的目錄和文件。
防御:將JS、CSS等資源文件部署在獨立服務器,使用獨立域名,其他文件不適用靜態URL訪問,動態參數不包含文件路徑信息。
信息加密技術及密鑰安全管理
為了保護網站的敏感數據,需要對這些敏感數據進行加密處理,信息加密技術分為三類:
單向散列加密
通過對不同輸入長度的信息進行散列計算,得到固定長度的輸出,散列計算是單向的,即不能對固定長度的輸出進行計算從而獲得輸入信息。
使用場景:密碼加密保存,生成信息摘要,計算具有高離散程度的隨機數等。
常用單向散列算法:MD5、SHA等。
對稱加密
加密和解密使用的密鑰是同一密鑰(或者可以互相推算)。
使用場景:Cookie加密,通信加密等。
優缺點:
- 優點:算法簡單,加密效率高,系統開銷小,適合對大量數據加密。
- 缺點:加解密使用同一個密鑰。
常用對稱加密算法:DES、RC算法。
非對稱加密
加密和解密使用的密鑰不同,其中一個對外界公開,叫做 公鑰 ,另一個只有所有者知道,被稱為 私鑰 。用公鑰加密的信息必須用私鑰才能解開,反之,用私鑰加密的信息只有公鑰才能解開。理論上不可能通過公鑰計算獲得私鑰。
使用場景:信息安全傳輸,數字簽名等。
常用非對稱加密算法:RSA算法。
HTTPS傳輸中瀏覽器使用的數字證書就是經過權威機構認證的非對稱加密的公鑰。
信息過濾與反垃圾
常用的信息過濾與反垃圾手段有以下幾種:
文本匹配
主要用來解決敏感詞過濾問題。
快速判斷信息中是否包含敏感詞方法:
- 正則匹配:適用于敏感詞較少,信息文本較短場景。正則表達式的效率一般較差。
- Trie樹及變種:算法本質是確定一個有限狀態的自動機,根據輸入數據進行狀態轉移。
分類算法
算法原理:先將批量已經分好類的樣本數據輸入分類算法進行訓練,可以得到一個分類模型,然后再利用分類算法結合分類模型對待處理郵件進行識別。
簡單實用的分類算法:貝葉斯分類
實用場景:反垃圾、信息自動分類等
黑名單
將需要過濾的內容加入到黑名單中,然后從黑名單中進行查找,如果找到,就過濾掉。
常用數據結構:Hash表、BloomFilter。
電子商務風險控制
交易安全是電子商務網站的底線。
風險
主要風險:
- 賬戶風險:如賬戶被黑客盜用、惡意注冊賬號等。
- 買家風險:買家惡意下單占用庫存進行不正當競爭;黃牛利用促銷搶購低價商品。
- 賣家風險:不良賣家進行惡意欺詐。
- 交易風險:信用卡盜刷、支付欺詐、洗錢套現等。
風控
風控手段包括 自動 和 人工 兩種。
自動風控技術:
- 規則引擎:將 業務規則 和 規則處理邏輯 分離的技術。缺點:規則沖突,難以維護,規則越多性能越差。
- 統計模型:使用統計模型進行風險控制。分類算法或者更復雜的機器學習算法。
關注作者:JAVA高級程序員
我會不定期在微頭條發放:(Java工程化、分布式架構、高并發、高性能、深入淺出、微服務架構、Spring、MyBatis、Netty、源碼分析)等技術學習資料,以及Java進階學習路線圖。