大型網站技術架構演進與性能優化(一) 構建大型網站:分佈式改造

一、構建大型網站:分佈式改造

1、爲什麼要做分佈式化
隨着業務的擴展和流量的爆發式增長,該系統很快達到了瓶頸,是不是一定要對它做分佈式改造呢?其實我們早期也嘗試用過一些高端的服務器(IOE),但一方面價格昂貴,另一方面這樣也阻擋不了瓶頸的到來,分佈式改造成爲必由之路。
分佈式改造必須先解決以下幾個問題:
第一,應用需要微服務化。即將大量粗粒度的應用邏輯拆小做服務化改造
第二,必須先建立分佈式服務框架。必須具備分佈式配置系統、分佈式RPC框架、異步消息系統、分佈式數據層、分佈式文件系統、服務的發現、註冊和管理。
第三,必須解決狀態一致性問題。
2、典型的分佈式架構
分佈式架構與傳統的單機架構最大的區別在於分佈式架構能解決兩個方向的擴展問題:一是橫向擴展,二是縱向擴展。
橫向擴展,主要用來解決應用架構上的容量問題。由於單臺服務器能支撐的服務能力始終是有限的,所以我們在架構上就必須做到能夠支持橫向服務能力的擴展。
縱向擴展,主要解決業務的擴展問題。當業務不斷擴展時,業務邏輯的複雜度也會不斷上升,所以在架構上要能根據功能的劃分進行縱向層次的劃分。
需要的分佈式中間件:
首先要有一個統一的負載均衡系統(LB/LVS)幫助平均分配外部請求的流量,將這些流量分配到後端的多臺機器上。
請求達到服務層,就需要解決服務之間的系統調用。包括同步調度的分佈式RPC框架、異步調度的分佈式消息框架、解決靜態配置信息的分佈式配置框架。
請求到達數據層。需要解決以下問題:第一,屏蔽不同數據庫的差異性,使底層數據庫的切換不影響上次應用代碼。第二,屏蔽應用層代碼對數據分佈的感知,使對數據的分區或分片不會影響應用代碼的編寫。
服務化和分佈式化:
服務化改造更多的是從業務架構的角度出發,目的是將業務做更細粒度的功能拆分,使業務邏輯更加清晰、邊界更加清楚且易於維護;服務化的另一個好處是收斂業務邏輯,通過接口標準化提供統一的訪問方式。
分佈式化更多的是從系統架構層面的角度出發,更多的是看訪問請求路徑,即一個請求必須先訪問什麼再訪問什麼一次訪問要經過哪些步驟才能最終有結果等。因此,這兩個是不同層面的工作。
3、分佈式配置框架
分佈式配置框架可以說是其他分佈式框架的基礎,因爲在分佈式系統中要做到所有機器節點都完全對等幾乎是不可能的,必然有某些機器或集羣存在某些差異,單同時又要保證程序代碼是一份,所以解決這些差異的唯一辦法就是差異化配置——配置框架就承擔着這些個性化的定製功能。
分佈式配置框架一般有一下兩種管理方式:
拉取模式和推送模式。
一般而言,如果對配置下發延時率比較敏感而且Client數據不是太大(千級別)時,推薦推送模式;而當Client數據在萬級別以上時推薦使用拉取模式。
4、分佈式RPC框架
服務註冊
服務發現
服務調度和負載均衡
統一的SDK封裝:服務框架需要提供一個統一的客戶端和服務端的標準接口規範,這樣可以減少業務開發的重複工作量。例如SDK會統一封裝通信協議、失敗重試以及封裝一些隱式參數傳遞(trace信息)。
Java通過提供一個統一的jar包,封裝了服務發佈和調用的接口,業務層只需要做些簡單的配置就能方便調用服務。
5、分佈式消息框架
實時消息
開源的RocketMQ、Kafka等
異步解耦
可以分開調用者和被調用者的處理邏輯,降低系統耦合,解決處理員之間的差異、數據結構之間的差異以及生產消費和消費者的速度差異。
主要保證兩點
最終的一致性:一致性要求不能丟消息,保證消費最終可達,如果最終不可達要反饋給發送方。
多消費端
一個消息是被多個訂閱者消費是典型的一種應用場景,多消費端非常適合用在單一事情觸發的場景中。
典型問題:
確認消息會否被消費(需要增加消費確認標識)
消息隊列需要有容錯能力(當某個消息失敗後,可以恢復重新投遞消息)
延時消息
典型的應用場景是比如預訂一張電影票的訂單產生後,用戶在15分鐘後仍然沒有付款,那麼系統會要求在15分鐘後取消該訂單,釋放座位。
6、分佈式數據層
主要解決數據的分庫分表、主備切換以及讀寫分離等問題。
讀寫分離要注意讀寫一致性的問題。
7、分佈式文件系統
當前開源的分佈式文件系統很多,像開源的TFS、FastDFS、GFS等。它們主要解決的是數據的高可用性和高性能問題。
8、應用的服務化改造
應用分層設計
應用分層設計很有必要。例如最起碼要對數據庫的訪問統一抽象出來形成數據層,而不是直接在代碼裏面寫SQL。
通常從垂直方向劃分應用,分成服務層、業務邏輯層和數據層,每一層儘量做到解耦:上層依賴下層,而下層不要反向依賴上層。
應用分層最核心的目的是每個層都會封裝一些信息、完成一些特定的功能需求,層與層之間通過接口交互,而且交互的數據是清晰和固定的,做到隔離和交互。可以從以下兩個方向判斷分層是否合理。
第一,如果我要增加一些新需求或者修改某些需求時,是否能清楚地知道要到哪層去完成,換句話說,這些分層的職責是否清晰。
第二,如果每個層對我的接口不變,那麼每個層內部的修改是否會導致其他層也發生修改,即每個層是否做到了收斂。
微服務化
微服務化,是從水平劃分的角度儘量把服務分得更細,每個業務只負責一個功能單元,這樣可以把這些微服務組合成更大的功能模塊。也就是有目的地拆小應用,形成單一職責從而提升系統可維護性、擴展性和開發效率。
9、分佈式化遇到的典型問題
集羣管理
例如Zookeeper的Leader選舉
共享鎖
通過使用Zookeeper實現
隊列管理
兩種類型隊列:同步隊列和FIFO方式進行入隊和出隊操作
通過使用Zookeeper實現
10、分佈式消息通道服務的設計
這個沒有接觸過。
例如:打車App每天要上傳大量的位置信息。
11、典型的分佈式集羣設計思路
當前的分佈式集羣管理中通常由兩種設計思路:一種是Master/Slaver模式;一種是無對等的設計思路。
12、總結
從剛開始的單應用單層級的結構轉換成多應用多層級的分佈式應用需要解決前面我們提高的衆多問題,而最核心的是要解決以下問題:
第一,縱向業務邏輯的分層拆分,要方便不同工種的程序開發人員的協作。例如前端和後端開發人員的協作效率。
第二,橫向不同業務系統的拆分,例如商品和會員系統獨立。
第三,系統的橫向和縱向的拆分必須首先解決好系統之間的連接問題,而這些系統之間的如何連接就是分佈式系統必須解決的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章