在前面的專欄裏,有同窗留言說想看看具體的架構設計文檔。因爲信息安全的緣由,再加上稍微複雜的系統,設計文檔都是幾十頁,所以專欄沒法直接給出詳細的文檔案例。但我認爲提供一個架構設計文檔模板仍是頗有必要的,能夠方便你在實際進行架構設計的時候更好地編寫相關文檔。我還之前面講過的「前浪微博」消息隊列爲例,給出架構設計中最重要的兩個文檔的模板和關鍵說明。這個案例文檔僅給出一些關鍵內容供你參考,部分細節沒法全面覆蓋或者徹底保證正確。數據庫
1. 需求介紹緩存
[需求介紹主要描述需求的背景、目標、範圍等]安全
隨着前浪微博業務的不斷髮展,業務上拆分的子系統愈來愈多,目前系統間的調用都是同步調用,由此帶來幾個明顯的系統問題:服務器
性能問題:當用戶發佈了一條微博後,微博發佈子系統須要同步調用「統計子系統」「審覈子系統」「獎勵子系統」等共 8 個子系統,性能很低。網絡
耦合問題:當新增一個子系統時,例如若是要增長「廣告子系統」,那麼廣告子系統須要開發新的接口給微博發佈子系統調用。架構
效率問題:每一個子系統提供的接口參數和實現都有一些細微的差異,致使每次都須要從新設計接口和聯調接口,開發團隊和測試團隊花費了許多重複工做量。運維
基於以上背景,咱們須要引入消息隊列進行系統解耦,將目前的同步調用改成異步通知。異步
2. 需求分析性能
[需求分析主要全方位地描述需求相關的信息]測試
5W
[5W 指 Who、When、What、Why、Where。
Who:需求利益干係人,包括開發者、使用者、購買者、決策者等。
When:需求使用時間,包括季節、時間、里程碑等。
What:需求的產出是什麼,包括系統、數據、文件、開發庫、平臺等。
Where:需求的應用場景,包括國家、地點、環境等,例如測試平臺只會在測試環境使用。
Why:需求須要解決的問題,一般和需求背景相關]
消息隊列的 5W 分析以下:
Who:消息隊列系統主要是業務子系統來使用,子系統發送消息或者接收消息。
When:當子系統須要發送異步通知的時候,須要使用消息隊列系統。
What:須要開發消息隊列系統。
Where:開發環境、測試環境、生產環境都須要部署。
Why:消息隊列系統將子系統解耦,將同步調用改成異步通知。
1H
[這裏的 How 不是設計方案也不是架構方案,而是關鍵業務流程。消息隊列系統這部份內容很簡單,但有的業務系統 1H 就是具體的用例了,有興趣的同窗能夠嘗試寫寫 ATM 機取款的業務流程。若是是複雜的業務系統,這部分也能夠獨立成「用例文檔」]
消息隊列有兩大核心功能:
業務子系統發送消息給消息隊列。
業務子系統從消息隊列獲取消息。
8C
[8C 指的是 8 個約束和限制,即 Constraints,包括性能 Performance、成本 Cost、時間 Time、可靠性 Reliability、安全性 Security、合規性 Compliance、技術性 Technology、兼容性 Compatibility]
注:需求中涉及的性能、成本、可靠性等僅僅是利益關聯方提出的訴求,不必定準確;若是通過分析有的約束沒有必要,或成本過高、難度太大,這些約束是能夠調整的。
性能:須要達到 Kafka 的性能水平。
成本:參考 XX 公司的設計方案,不超過 10 臺服務器。
時間:指望 3 個月內上線第一個版本,在兩個業務嘗試使用。
可靠性:按照業務的要求,消息隊列系統的可靠性須要達到 99.99%。
安全性:消息隊列系統僅在生產環境內網使用,無需考慮網絡安全;如消息中有敏感信息,消息發送方須要自行進行加密,消息隊列系統自己不考慮通用的加密。
合規性:消息隊列系統須要按照公司目前的 DevOps 規範進行開發。
技術性:目前團隊主要研發人員是 Java,最好用 Java 開發。
兼容性:以前沒有相似系統,無需考慮兼容性。
3. 複雜度分析
[分析需求的複雜度,複雜度常見的有高可用、高性能、可擴展等,具體分析方法請參考專欄前面的內容]
注:文檔的內容省略了分析過程,實際操做的時候每一個約束和限制都要有詳細的邏輯推導,避免徹底拍腦殼式決策,具體請參考專欄第 10 期的分析。
高可用
對於微博子系統來講,若是消息丟了,致使沒有審覈,而後觸犯了國家法律法規,則是很是嚴重的事情;對於等級子系統來講,若是用戶達到相應等級後,系統沒有給他獎品和專屬服務,則 VIP 用戶會很不滿意,致使用戶流失從而損失收入,雖然也比較關鍵,但沒有審覈子系統丟消息那麼嚴重。
綜合來看,消息隊列須要高可用性,包括消息寫入、消息存儲、消息讀取都須要保證高可用性。
高性能
前浪微博系統用戶天天發送 1000 萬條微博,那麼微博子系統一天會產生 1000 萬條消息,平均一條消息有 10 個子系統讀取,那麼其餘子系統讀取的消息大約是 1 億次。將數據按照秒來計算,一天內平均每秒寫入消息數爲 115 條,每秒讀取的消息數是 1150 條;再考慮系統的讀寫並非徹底平均的,設計的目標應該以峯值來計算。峯值通常取平均值的 3 倍,那麼消息隊列系統的 TPS 是 345,QPS 是 3450,考慮必定的性能餘量。因爲如今的基數較低,爲了預留必定的系統容量應對後續業務的發展,咱們將設計目標設定爲峯值的 4 倍,所以最終的性能要求是:TPS 爲 1380,QPS 爲 13800。TPS 爲 1380 並不高,但 QPS 爲 13800 已經比較高了,所以高性能讀取是複雜度之一。
可擴展
消息隊列的功能很明確,基本無須擴展,所以可擴展性不是這個消息隊列的關鍵複雜度。
4. 備選方案
[備選方案設計,至少 3 個備選方案,每一個備選方案須要描述關鍵的實現,無須描述具體的實現細節。此處省略具體方案描述,詳細請參考專欄第 11 期]
備選方案 1:直接引入開源 Kafka
[此處省略方案描述]
備選方案 2:集羣 + MySQL 存儲
[此處省略方案描述]
備選方案 3:集羣 + 自研存儲
[此處省略方案描述]
5. 備選方案評估
[備選方案 360 度環評,詳細請參考專欄第 12 期。注意備選方案評估的內容會根據評估會議的結果進行修改,也就是說架構師首先給出本身的備選方案評估,而後舉行備選方案評估會議,再根據會議結論修改備選方案文檔]
[備選方案評估後會選擇一個方案落地實施,架構設計文檔就是用來詳細描述細化方案的]
1. 整體方案
[整體方案須要從總體上描述方案的結構,其核心內容就是架構圖,以及針對架構圖的描述,包括模塊或者子系統的職責描述、核心流程]
2. 架構總覽
[架構總覽給出架構圖以及架構的描述]
架構關鍵設計點:
採用數據分散集羣的架構,集羣中的服務器進行分組,每一個分組存儲一部分消息數據。
每一個分組包含一臺主 MySQL 和一臺備 MySQL,分組內主備數據複製,分組間數據不一樣步。
正常狀況下,分組內的主服務器對外提供消息寫入和消息讀取服務,備服務器不對外提供服務;主服務器宕機的狀況下,備服務器對外提供消息讀取的服務。
客戶端採起輪詢的策略寫入和讀取消息。
3. 核心流程
[此處省略流程描述]
[此處省略流程描述]
4. 詳細設計
[詳細設計須要描述具體的實現細節]
高可用設計
業務服務器中嵌入消息隊列系統提供的 SDK,SDK 支持輪詢發送消息,當某個分組的主服務器沒法發送消息時,SDK 挑選下一個分組主服務器重發消息,依次嘗試全部主服務器直到發送成功;若是所有主服務器都沒法發送,SDK 能夠緩存消息,也能夠直接丟棄消息,具體策略能夠在啓動 SDK 的時候經過配置指定。
若是 SDK 緩存了一些消息未發送,此時剛好業務服務器又重啓,則全部緩存的消息將永久丟失,這種狀況 SDK 不作處理,業務方須要針對某些很是關鍵的消息本身實現永久存儲的功能。
消息存儲在 MySQL 中,每一個分組有一主一備兩臺 MySQL 服務器,MySQL 服務器之間複製消息以保證消息存儲高可用。若是主備間出現複製延遲,剛好此時 MySQL 主服務器宕機致使數據沒法恢復,則部分消息會永久丟失,這種狀況不作針對性設計,DBA 須要對主備間的複製延遲進行監控,當複製延遲超過 30 秒的時候須要及時告警並進行處理。
每一個分組有一主一備兩臺服務器,主服務器支持發送和讀取消息,備服務器只支持讀取消息,當主服務器正常的時候備服務器不對外提供服務,只有備服務器判斷主服務器故障的時候纔對外提供消息讀取服務。
主備服務器的角色和分組信息經過配置指定,經過 ZooKeeper 進行狀態判斷和決策。主備服務器啓動的時候分別鏈接到 ZooKeeper,在 /MQ/Server/[group] 目錄下創建 EPHEMERAL 節點,假設分組名稱爲 group1,則主服務器節點爲 /MQ/Server/group1/master,備服務器的節點爲 /MQ/Server/group1/slave。節點的超時時間能夠配置,默認爲 10 秒。
高性能設計
[此處省略具體設計]
可擴展設計
[此處省略具體設計。若是方案不涉及,能夠簡單寫上「無」,表示設計者有考慮但不須要設計;不然若是徹底不寫的話,方案評審的時候可能會被認爲是遺漏了設計點]
無
安全設計
消息隊列系統須要提供權限控制功能,權限控制包括兩部分:身份識別和隊列權限控制。
消息隊列系統給業務子系統分配身份標識和接入 key,SDK 首先須要創建鏈接並進行身份校驗,消息隊列服務器會中斷校驗不經過的鏈接。所以,任何業務子系統若是想接入消息隊列系統,都必須首先申請身份標識和接入 key,經過這種方式來防止惡意系統任意接入。
某些隊列信息可能比較敏感,只容許部分子系統發送或者讀取,消息隊列系統將隊列權限保存在配置文件中,當收到發送或者讀取消息的請求時,首先須要根據業務子系統的身份標識以及配置的權限信息來判斷業務子系統是否有權限,若是沒有權限則拒絕服務。
其餘設計
[其餘設計包括上述之外的其餘設計考慮點,例如指定開發語言、符合公司的某些標準等,若是篇幅較長,也能夠獨立進行描述]
消息隊列系統須要接入公司已有的運維平臺,經過運維平臺發佈和部署。
消息隊列系統須要輸出日誌給公司已有的監控平臺,經過監控平臺監控消息隊列系統的健康狀態,包括髮送消息的數量、發送消息的大小、積壓消息的數量等,詳細監控指標在後續設計方案中列出。
部署方案
[部署方案主要包括硬件要求、服務器部署方式、組網方式等]
消息隊列系統的服務器和數據庫服務器採起混布的方式部署,即:一臺服務器上,部署同一分組的主服務器和主 MySQL,或者備服務器和備 MySQL。由於消息隊列服務器主要是 CPU 密集型,而 MySQL 是磁盤密集型的,因此二者混布互相影響的概率不大。
硬件的基本要求:32 核 48G 內存 512G SSD 硬盤,考慮到消息隊列系統動態擴容的需求不高,且對性能要求較高,所以須要使用物理服務器,不採用虛擬機。
5. 架構演進規劃
[一般狀況下,規劃和設計的需求比較完善,但若是一次性所有作完,項目週期可能會很長,所以能夠採起分階段實施,即:第一期作什麼、第二期作什麼,以此類推]
整個消息隊列系統分三期實現:
第一期:實現消息發送、權限控制功能,預計時間 3 個月。
第二期:實現消息讀取功能,預計時間 1 個月。
第三期:實現主備基於 ZooKeeper 切換的功能,預計時間 2 周。