1. 程式人生 > >Web應用架構演進及系統性能、穩定性所需要解決的問題

Web應用架構演進及系統性能、穩定性所需要解決的問題

Web應用架構演進

  1. 專案起步階段

    在專案起步階段,系統訪問量不大,業務比較單一,且需求緊,需要快速上線,這個時候一般瀑布式開發,單系統、單庫、單快取叢集。

    這裡寫圖片描述

  2. 業務範圍擴大,根據業務邊界拆分

    在業務範圍擴大過程中,單系統會逐漸變得臃腫龐雜,業務耦合越來越嚴重,改動小可能影響會很大,有時候可能因為一處細小的錯誤導致全站宕機。
    當前階段最直接的辦法就是根據業務邊界進行拆分,每個業務模組由專門的開發人員進行維護,做到專而精。
    這裡寫圖片描述

  3. 訪問量級增大,系統性能考慮提上日程

    在系統的訪問量級變大之後,對於系統性能方面考慮就要提上日程了,以前可能單庫就搞定的事情現在需要分庫分表了,以前把量全部往資料庫打都不要緊的現在需要考慮哪些資料需要做預熱了,以前很多的非核心邏輯在主流程同步執行的需要考慮非同步去執行了。而且在訪問量這麼大的條件下,對於系統的穩定性要求會更高,以前掛1分鐘可能都沒請求進來,現在掛1分鐘可能是上百萬請求異常。
    該系統中由於存在需要根據多欄位去檢索資訊,所以會有一個索引庫的概念,通過在索引庫去查詢資訊所在分庫,但是這種模型對於讀能力是可以水平擴充套件的,而寫能力則是有單點瓶頸,有待優化。
    這裡寫圖片描述

  4. 多機房容災
    上一步完成之後,對於單機房的可用性已經有一定的保障,要做到服務的持續可用,還得繼續發展做網路分割槽,保證一個網路分割槽下的整個叢集全部掛掉,另外的網路分割槽也可繼續提供服務。
    在介紹網路分割槽之前,先來介紹下CAP定理,在分散式系統中,不可能同時滿足三點,C,consistence資料一致性,A,availability高可用性,P,partition tolerance容忍網路分割槽;如果有了網路分割槽,要麼選擇不同分割槽都可以寫資料,喪失部分資料一致性能力,通過最終一致性保證不同分割槽下資料一致;要麼選擇只有一個分割槽在寫資料,喪失寫的高可用。
    先來看看國內使用較多的模式,兩地三中心,同城兩個機房可同時提供服務,寫資料可一個機房寫也可以兩個機房都寫再同步,異地機房做冷備,一般來說同城機房之間50公里的光纖距離,資料同步延時在1~2ms,是一個可接受的範圍,而異地機房同步延時可能超過100ms;選擇這種方式整體來說就會簡單一些。

    這裡寫圖片描述

    一個異地機房就這麼一直處於空閒狀態總覺得代價挺大的,完全部署了一套卻長期派不上用場,而且一旦主機房出問題了,冷備機房長期未使用,對於這個機房是否能完全接管下來還是個未知數;那麼接下來又做了一些改進,把部分只讀流量引導到異地機房;多了只讀請求後,就需要考慮一個問題,如果使用者剛註冊完去訪問使用者資訊,結果使用者被路由到異地機房,資料還沒同步過來,發現使用者不存在了怎麼處理,可能的一種做法是發現沒有資料了就跑去源機房取一次試試。

    這裡寫圖片描述

    異地只讀這種方式在某些業務場景下發現能拎出來的只讀業務很難抽象並區分開,這樣的話異地只讀的機房還是意義不太大,那再做好一點就要往異地多活的方向發展了,每個城市最少一個機房,每個機房都會有讀寫流量,允許多點寫;那麼這開始考慮的問題就要多太多了,舉兩個例子,
    1、機房A和B現在分別接管百分之五十流量,現在想把A機房流量再切一部分到B機房,那麼就可能存在在A機房寫入了一些資料,再到B機房讀取發現數據不一致了,怎麼做到切換過程完全一致
    2、如果使用者現在機房A註冊了,機房A某個時間點掛了,流量切到機房B,使用者又使用這個資訊註冊了一次,但是密碼可能換了一個,這個時候機房A又恢復了,怎麼對這個資料做恢復
    類似這種細節點應該還有很多,這裡還缺少實戰經驗,就不做太多介紹了,也希望後續能夠有機會參與到異地多活的設計與開發,
    再回過頭來看看,雖然細節點有許多要考慮的,做異地多活的話還有一些基本原則是比較明確的,首先對一個使用者做路由的時候,不能說第一次訪問給路由到A機房,第二次訪問又給路由到B機房,這個對一致性要求太高,所以這裡需要把路由策略做到同一個使用者請求每次訪問路由到一處;然後因為延時問題如果存在多次跨機房呼叫對於使用者體驗造成嚴重影響,需要保證同機房流量閉環;另外對於多中心資料同步的延時一定要有感知,對於資料的一致性需要有一定的校驗措施。
    那麼異地多活做完之後呢,好像系統已經很強大了,就算機房光纜被挖斷也不用擔心了。

    這裡寫圖片描述

服務化

1、 什麼是服務化

  • 服務拆分

    這裡寫圖片描述

  • 服務治理

    這裡寫圖片描述

    2、 服務化可以帶來什麼

  • 業務職責清晰

  • 模組複用
  • 自主測試及上線
  • 獨立伸縮
  • 故障隔離

系統性能

  1. 壓測介紹

    • 線下壓測

      單機壓測

    • 線上壓測

      全鏈路壓測

      逐漸引導流量到一臺機器

    • 線上監控(CAT)

    • 線下調優環境

      線上同等配置機器及資料量

    • 調優目標

      TPS、平均響應時間、最大響應時間、錯誤率
      CPU、記憶體使用率
      穩定

    記憶體趨勢在每一個最高點或最低點都是呈現上升趨勢,長期壓會引發OOM,需要排查記憶體佔用物件。

    會OOM的走勢

    對於穩定的系統壓測,走勢應該如下圖

    穩定的走勢

  2. 調優舉例

    • Tomcat session使記憶體爆滿

      上圖中可看見有tomcat的StandardSession佔比也較高,這邊當時遇到這個問題的場景是說我們封裝了session放到redis中,但是在封裝過程中錯誤呼叫了原生的request.getSession導致產生大量session物件,預設session超時30分鐘,30分鐘內無法被釋放,如果持續生成會導致OOM。

    • Drools的高併發使用HashMap導致假死

    這裡寫圖片描述

    • IO密集型服務做非同步化處理

    • 讀多寫少,使用分散式快取及預熱處理

系統穩定性

  1. SLA

    SLA,Service Level Agreement

    SLA體現在對容量(QPS)、效能(RT)、程度(分佈情況;可⽤用性、出錯率)的約束

    SLA保障是服務穩定性的生命線和服務架構升級的動力

    這裡寫圖片描述

  2. 高可用

    系統無單點,不僅包括軟體的部署以及機房的電源、交換機等硬體裝置。

    這裡寫圖片描述

  3. 強依賴轉弱依賴

    梳理系統核心流程,將非核心依賴轉為弱依賴

    這裡寫圖片描述

  4. 防禦式程式設計

    防禦式程式設計核心是除了自身系統,對上游和下游系統的呼叫量、穩定性和服務質量都持質疑態度;

    一旦上游或下游服務出現任何問題,通過預設策略保證自身系統的穩定。

    這裡寫圖片描述

    客戶端超時,呼叫任何外部服務時需要設定合理的超時時間,避免因為外部服務故障引起自身服務的一系列故障

    服務端超時,對於在等待佇列中的任務,如果客戶端已經超過等待時間則拋棄請求,避免引發雪崩

    熔斷,過載保護措施;熔斷策略和恢復策略

    這裡寫圖片描述

    服務降級,對弱依賴服務做好開關或多策略切換機制,保證在對方服務掛掉時遮蔽服務呼叫或切換其他執行策略

  5. 資源池隔離

    不同業務使用的資源池隔離使用:資料庫、快取、連線池、執行緒池

    這裡寫圖片描述

  6. 防刷和限流

    限制惡意提交

    控制請求頻次;請求資料特徵;限制分為降低頻次和限制一定時間使用
    
    針對客戶端介面通過動態庫加簽及自定義協議等策略提高刷介面門檻
    
    針對網頁介面抓取機器特徵及使用者行為做風險判斷
    

    針對服務端服務能力限制介面請求總量

  7. 削峰以及真/假排隊

    通過傳送訊息的方式,後端服務根據能力接收訊息處理的方式進行削峰填谷。

    假排隊是描述系統對於使用者的先進先出無特別感知,只要使用者請求進來滿足可進入條件即可放入。

    這裡寫圖片描述

    真排隊描述使用者必須根據先來後到的順序進行排隊進入。

    這裡寫圖片描述

  8. 多機房容災

    同城雙活

    兩地三中心

    異地只讀

    異地多活

  9. 灰度釋出

    通過灰度釋出驗證新功能,減小影響範圍

    這裡寫圖片描述

系統監控

  1. 業務監控

    訂單量,支付成功率;各渠道支付成功量、各渠道支付成功率;PC/H5支付成功量;收銀臺訪問量

    業務監控最能反應當前系統執行狀態,如果業務資料突然減少很多,必然出現問題。

    這裡寫圖片描述

  2. 業務告警,通過日誌中ERROR和FATAL進行郵件、簡訊通知

  3. 應用監控

    呼叫頻次,各介面TPS,平均響應時長,最長響應時長,http status

    這裡寫圖片描述

  4. 系統監控

    CPU、記憶體、負載、網路頻寬、IO、磁碟空間、服務埠

    這裡寫圖片描述

  5. 全鏈路監控系統

    通過全域性唯一traceID從業務入口帶到底端,然後通過日誌埋點寫入到大資料平臺進行分析展示。

    這裡寫圖片描述

業務可擴充套件性

  1. 業務邊界

    說大一點的層面,會員、眾籌這些商品系統,在下單前都是在各自系統下維護,包括可能存在購物車、商品詳情等,下單後準備支付的流程都在錢包系統,支付完再由錢包通知回各商品系統,如果有實體發貨會有另外的系統做維護配送資訊等。
    再往小層面,各業務子系統,比如錢包目前存在銀行卡業務、賬戶餘額業務、收銀臺支付業務、充值業務等,剝離完各自業務系統,後續有業務需求變更時,就只用根據業務的職責去修改對應系統。
    如果都做在一起,那後續需求變更的時候很可能就是往哪裡做最快就往哪裡做了,長期下去會導致各業務之間耦合嚴重;剝離到不同業務系統可以從根源上杜絕這個問題。

  2. 業務分層

    在對業務邊界有了明確區分後,還需要對這些業務系統做一個良好的分層,每一層僅依賴本層和下層。