1. 程式人生 > >“不戰而屈人之兵”思想對專案架構設計的戰略指導

“不戰而屈人之兵”思想對專案架構設計的戰略指導

“不戰而屈人之兵”作為戰略指導的思想境界,把全勝作為戰爭的最高目標,以最小代價達成戰爭目的。

對專案而言,我們要考慮專案的應用場景,使用者規模和資料處理能力,以及專案未來3年的目標等。在應用場景的設計中,會考慮業務和技術的結合度量,業務的規模和流程設計。技術的選型沒有涉及到。使用者規模和資料處理能力,會考慮技術選型和架構設計。具體要考慮架構設計。架構中重要的核心指標:效能、可用性、伸縮性、擴充套件性的等架構指標。

一、效能

效能就是核心要素之一,具體如下:

(1)系統前端效能優化:

  1. 瀏覽器訪問優化(瀏覽器快取、頁面壓縮傳輸、合理佈局頁面、減少Cookie傳輸)
  • 減少http請求。避免建立太多通訊鏈路。將js、css、圖片檔案儘可能合併。避免太多請求。同時,對於系統的後端請求也儘可能進行合理的設計,來避免出現太多互動。
  • 使用瀏覽器的快取。http頭設定Cache-Control和Expires.js檔名比如可以帶時間戳。一旦有更新則更新時間戳,否則快取;同時儘量避免同一時間更新大量靜態資源。
  • 對靜態資源進行壓縮。
  • css放置在頁面最上方,js放下最下面。以提前進行css渲染。同時避免js帶來的頁面阻塞。但需要case by case。比如頁面dom節點需要依賴js生成,則可視情況改變檔案位置。
  • 減少cookie傳輸。同時讓靜態資源有獨立域名,傳送靜態資源請求時候不傳送cookie。以此減少傳輸代價。cookie可以通過document.cookie獲取。

2.CDN加速

  • 快取圖片、檔案、CSS以及script指令碼。但是pc上的CDN加速效果要好於移動端。經過調研發現,last-mile的延遲越高,CDN的相對有效性越差(具體見文章為什麼CDN對移動客戶端加速“沒有”效果)。

3.反向代理

  • 可以提供七層負載均衡(http請求進行均衡策略),並且可以提供靜態資源的快取,請求轉發,防止網路攻擊等。比較流行的有nginx。

(2)服務的效能優化:

在高併發請求的情況下,可以將多臺應用伺服器組成一個叢集共同對外服務,提高整體處理能力,改善效能,具體如下:

1.分散式快取(網站效能優化的第一定律:優先考慮使用快取優化效能)

  1. 一般來說,存入cache的資料的讀寫比在2:1以上;且應該是熱點資料。
  2. 需要考慮如果採用快取則可能帶來的資料短期內的不一致,或者如果實時更新快取可能帶來的效能和資源開銷。
  3. 需要考慮cache一旦失效,大量請求直接命中DB可能帶來的服務效能雪崩。所以可以對cache採用叢集化部署,以此避免丟失過多資料造成服務壓力陡增。
  4. 對於熱點資料考慮進行快取的預熱載入。比如高峰期來臨前,先將熱點資料提前存入快取。以此提高高峰期的服務效能。
  5. 為了避免惡意攻擊,一直query不存在的資料,導致cache無法命中而頻繁訪問DB,可以將不存在的資料也進行快取並定期清理。同時有機制對惡意請求進行識別和封禁。
  6. 分散式快取應該去中心化並集中管理。通過不同例項間的互不通訊和同構來保證可擴充套件性,並降低系統複雜度。

2.非同步化

通過分散式訊息佇列來實現削峰的目的。通過業務配合技術來解決問題。

3.叢集

採用叢集也是服務虛擬化的一個體現。用以避免單點問題,同時提供更加高可用,高效能的服務。

4.程式碼優化

  1. 多執行緒中,如果是密集型計算,執行緒數不宜超過CPU核數。如果是IO處理,則執行緒數=[任務執行時間/(任務執行時間-IO等待時間)] * CPU核數。除此之外,我們應該將物件設計成無狀態物件,多采用區域性物件,適當將鎖細化。
  2. 進行資源複用。比如採用單例模式,比如採用連線池。
  3. 合理設定JVM引數。

5.儲存效能優化

關係型資料庫的索引採用B+樹進行實現。而很多的nosql資料庫則採用了LSM樹進行儲存。LSM在記憶體中保留最新增刪改查的資料,直到記憶體無法放下,則與磁碟的下一級LSM樹進行merge。所以對於寫操作較多,而讀操作更多的是查詢最近寫入資料的場景,其效能遠高於b+樹;採用HDFS結合map reduce進行海量資料儲存和分析。其能自動進行併發訪問和冗餘備份,具有很高的可靠性。其等於是實現了RAID的功能。

(3)資料訪問介面優化:

資料庫層其實是最脆弱的一層,一般在應用設計時在上游就需要把請求攔截掉,資料庫層只承擔“能力範圍內”的訪問請求,所以,我們通過在服務層引入佇列和快取,讓最底層的資料庫高枕無憂。

(4)網站效能指標

  1. 響應時間。
  2. 併發數。如果暫時沒有對應的準確監控,針對不同業務模型,可以有不一樣的併發數的預估。我們的系統進行峰值併發數預估的話,有一種比較粗略的計算方式,即全天請求平均每秒併發數 * 3。
  3. 吞吐量。比較常見的有QPS(每秒查詢數)、HPS(每秒http請求數)以及TPS(每秒處理事務數)。
  4. 效能計數器。包括系統負載、執行緒數、cpu、記憶體使用情況等。可以用top、free、cat /proc/cpuinfo等命令來檢視。系統負載的定義為當前被CPU執行的執行緒數/等待被CPU執行的匯流排程數。當其值與邏輯cpu個數相同時是最佳狀態,其代表所有的資源都被最大限度地被利用。但也有人認為當負載為0.7倍邏輯CPU數時最佳。

二、高可用性

衡量一個系統架構設計是否滿足高可用的目標,就是假設系統中任何一臺或者多臺伺服器宕機時,以及出現各種不可預期的問題時,系統整體是否依然可用。一般就三個手段、冗餘、叢集化、分散式。網站高可用的主要手段就是冗餘,應用部署在多臺伺服器上同時提供服務,資料儲存在多臺伺服器上相互備份,任何一臺伺服器都不會影響應用的整體可以,通常的實現手段即把多臺伺服器通過負載均衡裝置組成一個叢集。  安全服務是指計算機網路提供的安全防護措施,包括認證服務、訪問控制、資料機密性服務、資料完整性服務和不可否認服務。特定的安全機制是用來實施安全服務的機制,包括加密機制、資料簽名機制、訪問控制機制、資料完整性機制、認證交換機制、流量填充機制、路由控制機制和公證機制。普遍性的安全機制不是為任何特定的服務而特設的,屬於安全管理方面,分為可信功能度、安全標記、事件檢測、安全審計跟蹤和安全恢復。

、高擴充套件性

擴充套件性(Extensibility)指對現有系統影響最小的情況下,系統功能可持續擴充套件或提升的能力。表現在系統基礎設施穩定不需要經常變更,應用之間較少依賴和耦合,當系統增加新功能時,不需要對現有系統的結構和程式碼進行修改。這個沒啥好說。擴充套件性依賴於前期良好的架構設計。合理業務邏輯抽象,水平/垂直切割分散式化等等。網站可擴充套件架構的主要手段是事件驅動架構和分散式服務。事件驅動通常利用訊息佇列實現,通過這種方式將訊息生產和處理邏輯分隔開。伺服器服務則是將業務和可複用服務分離開來,通過分散式服務框架呼叫。新增加產品可用通過呼叫可複用的服務來實現自身的業務邏輯,而對現有產品沒有任何影響。

、高伸縮性

服務儘量同構。DB、cache在考慮分散式時儘量提前設計好擴充套件方案。也可以採用一些主流的對水平伸縮支援較好的nosql、memcached、hbase等。