架構模式
方向
- 高內聚、低耦合。便於開發和維護、不同模塊分佈式部署提高併發能力。
- 業務中臺重點需要關注的是性能和可用性。伸縮性、擴展性、安全性需要兼顧。
優化方式
- 分層。應用的橫向切分,做到分散關注、鬆散耦合、邏輯複用、標準定義。
- 應用層:具體業務和視圖展示,和用戶直接交互。
- 服務層:提供服務支持。
- 數據層:提供存儲服務,如數據庫、緩存、搜索引擎、文件。
- 分割。應用的縱向切分,通常按照不同業務劃分,專人做專事、不同等級保障。
- 分佈式。網絡穩定性、數據一致性需要考慮。
- 包括服務應用、靜態資源、數據存儲、計算、配置、鎖、文件的分佈式。
- 集羣。負載均衡和失效轉移提供併發特效和可用性。
- 緩存。在數據熱點不均勻、數據有一定有效期的情況下使用。
- 異步。提高可用性、減少rt、削峯。
- 冗餘。包括集羣備份、冷熱備份、災備數據中心。
- 自動化。發佈過程、代碼管理、安全監測、監控、失效轉移恢復、降級、分配資源都可以自動化。
- 安全。密碼、驗證碼、加密、過濾、風控等。
核心要素
性能
- 包括響應時間(rt)、併發數(同時處理的請求)、吞吐量(QPS TPS HPS)、服務器參數(load CPU等)。
- 針對鏈路瓶頸優化。比如gc,redis,db等。
應用層優化
- 瀏覽器訪問優化。
- 減少http請求。合併js,css,圖片。
- 瀏覽器緩存。
- 文件壓縮。服務端壓縮,瀏覽器解壓,時間換空間。
- css在上,js在下。防止阻塞頁面加載:加載完所有css之後渲染,加載js後立刻執行。
- 減少cookie傳輸量。
- CDN加速。緩存靜態文件,如css,js,html,圖片,視頻等。
- 反向代理。安全、緩存靜態內容、負載均衡。
服務層優化
- 分佈式緩存。減少訪問時間和計算時間。
- 緩存的數據不應頻繁修改(讀寫比>2),有熱點訪問。
- 需要處理實時問題帶來的不一致和髒讀。
- 對於緩存穿透、擊穿、雪崩的應對方案。
- 需要提高緩存命中率。
- 讀寫分離和代理緩存 解決熱key問題。
- 本地緩存。項目中使用高性能的Caffeine。深入理解caffeine,參考1,參考2。
- 異步。消息隊列,異步dubbo等。
- 集羣。提升整體的qps等。
- 代碼優化。
- 多線程。由於IO阻塞和多CPU,提高資源利用率。可以用貧血模型對象、局部對象,注意併發資源處理線程安全問題。
- 資源複用。單例和對象池(線程池、數據庫連接池等)。
- 垃圾回收。合理設置GC參數,儘量減少Full GC,或者G1避免。
數據層優化
- 固態硬盤。
- LSM樹更新無需訪問磁盤,記錄更新的步驟。適合寫爲主,讀操作集中在最近寫入數據上。
- 參考hbase寫入流程。
- HDFS。管理block,每個block至少兩個備份。
- NameNode提供元數據服務,管理block分配,相當於FAT。DataNode提供數據服務。
- 基於HDFS的Hbase。Hbase的region,Hbase的rowkey。
可用性
應用層優化
- 無狀態性:不保存業務的上下文,只根據請求參數響應。通過session服務器管理狀態。
- 負載均衡,實現無狀態服務的失效轉移。
服務層優化
- 負載均衡,失效轉移。
- 服務分級。高優先級的服務佔用更好的硬件資源,部署在不同的宿主機上,甚至異地容災。
- 超時設置。服務方掛掉,超時重試或者使用降級策略。
- 異步調用。解耦,不影響調用方。需要調用結果進行下一步操作的不適合異步。
- 服務降級。
- 拒絕服務。按照優先級或者隨機拒絕,降低併發數,保證部分請求成功。
- 關閉功能。關閉不重要的功能,減少開銷。
- 冪等性設計。保證多次調用和一次調用結果相同。
數據層優化
CAP原理:一致性,可用性,分區耐受性(伸縮性)。
一致性:多副本時,所有程序訪問得到相同的數據。
可用性:任何時候任何程序都可以讀寫訪問,有好的響應性能。
分區耐受性:可跨網絡分區線性伸縮,可靠性強。
大型網站通常會犧牲強一致性保證數據的用戶一致性,即AP。
- 數據備份。
- 異步熱備。例如mysql主從。
- 同步熱備。存儲服務器沒有主從之分。
- 失效轉移。失效確認、訪問轉移、數據恢復(從健康的服務器複製數據)。
軟件優化
- 自動化發佈、自動化測試。
- 預發佈驗證。預發機器不配置在對外的負載均衡服務器,或者需要帶特定header才能訪問。
- 灰度發佈。
- 監控數據採集和管理。如cat監控告警,日誌平臺等。
伸縮性
- 增加資源規模增加整體的吞吐量。
- 應用服務器負載均衡。大型網站通常使用修改mac地址的數據鏈路層負載均衡——三角傳輸模式。
- 分佈式緩存使用一致性hash+虛擬節點。
- 存儲層。cobar伸縮,hbase的region分裂。
擴展性
- 系統架構層面的開閉原則。需要模塊化,並降低模塊的耦合、提高模塊的複用性。