梳理了一下架構設計和編碼中一些需要注意的地方,供大家參考。
架構原則
- 避免過度設計:最簡單的方案最容易實現和維護,也可以避免浪費資源。但方案中需要包括擴充套件。
- 冗餘設計:對服務、資料庫的做結點冗餘,保證服務的高可用。通過資料庫主從模式、應用叢集來實現。
- 多活資料中心:為了容災,從根本上保障應用的高可用性。需要構建多活的資料中心,以防止一個資料中心由於不可控因素出現故障後,引起整個系統的不可用。
- 無狀態設計:API、介面等的設計不能有前後依賴關係,一個資源不受其他資源改動的影響。無狀態的系統才能更好地進行擴充套件。如果非得有狀態,則要麼客戶端管理狀態,要麼服務端用分散式快取管理狀態。
- 可回滾:對於任何業務尤其是關鍵業務,都具有恢復機制。可以使用基於日誌的WAL、基於事件的Event sourcing等來實現可回滾。
- 可禁用/自我保護:具有限流機制,當上遊的流量超過自身的負載能力時,能夠拒絕溢位的請求。可以通過手動開關或者自動開關(監測異常流量行為),在應用前端擋住流量。
- 問題可追蹤:當系統出現問題時,能夠定位請求的軌跡、每一步的請求資訊等。分散式鏈路追蹤系統即解決的此方面的問題。
- 可監控:可監控是保障系統能夠穩定執行的關鍵。包括對業務邏輯的監控、應用程式的監控以及應用依賴的CPU、硬碟等系統資源的監控。每一個系統都需要做好這幾個層面的監控。
- 故障隔離:將系統依賴的資源(執行緒、CPU)和服務隔離開來能夠使得某個服務的故障不會影響其他服務的呼叫。通過執行緒池或者分散部署結點可以對故障進行隔離。
- 成熟可控的技術選型:使用市面上主流、成熟、文件、支援資源多的技術,選擇合適的而非最火的技術實現系統。
- 梯級儲存:記憶體->SSD硬碟->傳統硬碟->磁帶,可以根據資料的重要性和生命週期對資料進行分級儲存。
- 快取設計:隔離請求與後端邏輯、儲存,是就近原則的一種機制。包括客戶端快取(預先下發資源)、Nginx快取、本地快取以及分散式快取。
- 非同步設計:對於呼叫方不關注結果或者允許結果延時返回的介面,採用佇列進行非同步響應能夠很大程度提高系統效能;呼叫其他服務的時候不去等待服務方返回結果直接返回,同樣能夠提升系統響應效能。非同步佇列也是解決分散式事務的常用手段。
- 前瞻性設計:根據行業經驗和預判,提前把可擴充套件性、後向相容性設計好。
- 水平擴充套件:相比起垂直擴充套件,能夠通過堆機器解決問題是最優先考慮的問題,系統的負載能力也才能接近無限擴充套件。此外,基於雲端計算技術根據系統的負載自動調整容量能夠在節省成本的同時保證服務的可用性。
- 小步構建和釋出:快速迭代專案,快速試錯。不能有跨度時間過長的專案規劃。
- 自動化:打包、測試的自動化稱為持續整合,部署的自動化稱為持續部署。自動化機制是快速迭代和試錯的基礎保證。
架構六步思考法
筆者對美團總架構師夏華夏一次分享提出的架構六步思考法的理解。
資料設計原則
- 注意儲存效率
- 減少事務
- 減少聯表查詢
- 適當使用索引
- 考慮使用快取
- 避免依賴於資料庫的運算功能(函式、儲存器、觸發器等),將負載放在更容易擴充套件的業務應用端
- 資料統計場景中,實時性要求較高的資料統計可以用Redis;非實時資料則可以使用單獨表,通過佇列非同步運算或者定時計算更新資料。此外,對於一致性要求較高的統計資料,需要依靠事務或者定時校對機制保證準確性。
系統響應效能提升五板斧
- 非同步:佇列緩衝、非同步請求。
- 併發:利用多CPU多執行緒執行業務邏輯。
- 就近原則:快取、梯度儲存。
- 減少IO:合併細粒度介面為粗粒度介面、頻繁的覆蓋操作可以只做最後一次操作。這裡一個需要特別注意的地方: 程式碼中儘量避免在迴圈中呼叫外部服務,更好的做法是使用粗粒度批量介面在迴圈外面只進行一次請求。
- 分割槽:頻繁訪問的資料集規模保持在合理的範圍。