大型網站背後的高性能系統架構設計

關注小編之後,私信回覆“666”,免費領取精心“秘製” Java學習資料微服務、分佈式、高併發、高可用、Spring Cloud、Dubbo等等資料,Java稀缺面試題,一共30G。

1. 性能測試

1.1. 性能指標

網站性能測試的主要指標有:

  • 響應時間 - 響應時間(RT)是指從客戶端發一個請求開始計時,到客戶端接收到從服務器端返回的響應結果結束所經歷的時間,響應時間由請求發送時間、網絡傳輸時間和服務器處理時間三部分組成。
  • 併發數 - 系統同時處理的請求、事務數。
  • 吞吐量 - TPS(每秒事務數)、HPS(每秒 HTTP 請求數)、QPS(每秒查詢數)。
  • 性能計數器 - 系統負載、對象與線程數、內存使用、CPU 使用、磁盤與網絡 IO 等。這些指標也是系統監控的重要參數。

1.2. 性能測試方法

  • 性能測試
  • 負載測試
  • 壓力測試
  • 穩定性測試

1.3. 性能測試報告

性能測試報告示例:

大型網站背後的高性能系統架構設計

1.4. 性能優化策略

  1. 性能分析 - 如果請求響應慢,存在性能問題。需要對請求經歷的各個環節逐一分析,排查可能出現性能瓶頸的地方,定位問題。檢查監控數據,分析影響性能的主要因素:內存、磁盤、網絡、CPU,可能是代碼或架構設計不合理,又或者是系統資源確實不足。
  2. 性能優化 - 性能優化根據網站分層架構,大致可分為前端性能優化、應用服務性能優化、存儲服務性能優化。

2. 前端性能優化

2.1. 瀏覽器訪問優化

  1. 減少 HTTP 請求 - HTTP 請求需要建立通信鏈路,進行數據傳輸,開銷高昂,所以減少 HTTP 請求數可以有效提高訪問性能。減少 HTTP 的主要手段是合併 Css、JavaScript、圖片。
  2. 使用瀏覽器緩存 - 因為靜態資源文件更新頻率低,可以緩存瀏覽器中以提高性能。設置 HTTP 頭中的 Cache-Control 和 Expires 屬性,可以設定瀏覽器緩存。
  3. 啟用壓縮 - 在服務器端壓縮靜態資源文件,在瀏覽器端解壓縮,可以有效減少傳輸的數據量。由於文本文件壓縮率可達 80% 以上,所以可以對靜態資源,如 Html、Css、JavaScrip 進行壓縮。
  4. CSS 放在頁面最上面,JavaScript 放在頁面最下面 - 瀏覽器會在下載完全部的 Css 後才對整個頁面進行渲染,所以最好的做法是將 Css 放在頁面最上面,讓瀏覽器儘快下載 Css;JavaScript 則相反,瀏覽器加載 JavaScript 後立即執行,可能會阻塞整個頁面,造成頁面顯示緩慢,因此 JavaScript 最好放在頁面最下面。
  5. 減少 Cookie 傳輸 - Cookie 包含在 HTTP 每次的請求和響應中,太大的 Cookie 會嚴重影響數據傳輸。

2.2. CDN

CDN 一般緩存的是靜態資源。

CDN 的本質仍然是一個緩存,而且將數據緩存在離用戶最近的地方,使用戶已最快速度獲取數據,即所謂網絡訪問第一跳。

大型網站背後的高性能系統架構設計

2.3. 反向代理

傳統代理服務器位於瀏覽器一側,代理瀏覽器將 HTTP 請求發送到互聯網上,而反向代理服務器位於網站機房一側,代理網站服務器接收 HTTP 請求。

大型網站背後的高性能系統架構設計

反向代理服務器可以配置緩存功能加速 Web 請求,當用戶第一次訪問靜態內容時,靜態內容就會被緩存在反向代理服務器上。

反向代理還可以實現負載均衡,通過負載均衡構建的集群可以提高系統總體處理能力。

因為所有請求都必須先經過反向代理服務器,所以可以屏蔽一些攻擊 IP,達到保護網站安全的作用。

3. 應用服務性能優化

3.1. 分佈式緩存

網站性能優化第一定律:優先考慮使用緩存優化性能。

緩存原理

緩存指將數據存儲在相對較高訪問速度的存儲介質中,以供系統處理。一方面緩存訪問速度快,可以減少數據訪問的時間,另一方面如果緩存的數據是經過計算處理得到的,那麼被緩存的數據無需重複計算即可直接使用,因此緩存還起到減少計算時間的作用。

緩存的本質是一個內存 HASH 表。

緩存主要用來存放那些讀寫比很高、很少變化的數據,如商品的類目信息,熱門詞的搜索列表信息、熱門商品信息等。

合理使用緩存

緩存數據的選擇:

  • 不要存儲頻繁修改的數據
  • 不要存儲非熱點數據

數據不一致和髒讀:

  • 緩存有有效期,所以存在一定時間的數據不一致和髒讀問題。如果不能接受,可以考慮使用數據更新立即更新緩存策略

需要考慮緩存問題:緩存雪崩、緩存穿透、緩存預熱

3.2. 異步操作

異步處理一般是通過分佈式消息隊列的方式。

異步處理可以解決一下問題:

  • 異步處理
  • 應用解耦
  • 流量削鋒
  • 日誌處理
  • 消息通訊

3.3. 使用集群

在高併發場景下,使用負載均衡技術為一個應用構建一個由多臺服務器組成的服務器集群,將併發訪問請求分發到多臺服務器上處理,避免單一服務器因負載壓力過大而響應緩慢,使用戶請求具有更好的響應延遲特性。

3.4. 代碼優化

多線程

從資源利用的角度看,使用多線程的原因主要有兩個:IO 阻塞和多 CPU。

線程數並非越多越好,那麼啟動多少線程合適呢?

有個參考公式:

啟動線程數 = (任務執行時間 / (任務執行時間 - IO 等待時間)) * CPU 內核數

最佳啟動線程數和 CPU 內核數成正比,和 IO 阻塞時間成反比。如果任務都是 CPU 計算型任務,那麼線程數最多不要超過 CPU 內核數,因為啟動再多線程,CPU 也來不及調度;相反如果是任務需要等待磁盤操作,網絡響應,那麼多啟動線程有助於任務並罰賭,提高系統吞吐量。

線程安全問題

  • 將對象設計為無狀態對象
  • 使用局部對象
  • 併發訪問資源時使用鎖

資源複用

應該儘量減少那些開銷很大的系統資源的創建和銷燬,如數據庫連接、網絡通信連接、線程、複雜對象等。從編程角度,資源複用主要有兩種模式:單例模式和對象池。

數據結構

根據具體場景,選擇合適的數據結構。

垃圾回收

如果 Web 應用運行在 JVM 等具有垃圾回收功能的環境中,那麼垃圾回收可能會對系統的性能特性產生巨大影響。立即垃圾回收機制有助於程序優化和參數調優,以及編寫內存安全的代碼。

4. 存儲性能優化

4.1. 機械鍵盤和固態硬盤

考慮使用固態硬盤替代機械鍵盤,因為它的讀寫速度更快。

4.2. B+數和 LSM 樹

傳統關係數據庫的數據庫索引一般都使用兩級索引的 B+ 樹結構,樹的層次最多三層。因此可能需要 5 次磁盤訪問才能更新一條記錄(三次磁盤訪問獲得數據索引及行 ID,然後再進行一次數據文件讀操作及一次數據文件寫操作)。

由於磁盤訪問是隨機的,傳統機械鍵盤在數據隨機訪問時性能較差,每次數據訪問都需要多次訪問磁盤影響數據訪問性能。

許多 Nosql 數據庫中的索引採用 LSM 樹作為主要數據結構。LSM 樹可視為一個 N 階合併樹。數據寫操作都在內存中進行。在 LSM 樹上進行一次數據更新不需要磁盤訪問,速度遠快於 B+ 樹。

4.3. RAID 和 HDFS

HDFS(分佈式文件系統) 更被大型網站所青睞。它可以配合 MapReduce 併發計算任務框架進行大數據處理,可以在整個集群上併發訪問所有磁盤,無需 RAID 支持。


分享到:


相關文章: