朱曄的互聯網架構實踐心得S1E9:架構評審一百問和設計文檔五要素
本文我會來說說我認為架構評審中應該看的一些點,以及我寫設計文檔的一些心得。助你在架構評審中過五關斬六將,助你寫出能讓人收藏點讚的設計文檔。
第一部分:技術架構評審一百問
架構評審或技術方案評審的價值在於集眾人的力量大家一起來分析看看方案裡是否有坑,方案上線後是否會遇到不可逾越的重大技術問題,提前儘可能把一些事情先考慮到提出質疑其實對項目的健康發展有很大的好處。很多公司都有架構評審委員會都有架構評審的流程,做業務的兄弟要麼看到這個流程往往心驚膽戰害怕自己做的方案被斃了咋整,要麼就是認為這是一種過場,隨便糊弄一點文檔發給委員會看一下就算過去了。我做過架構評審委員也做過提交評審方案的業務兄弟,不管哪個角色我都不害怕而是喜歡這一流程,評審這個事情做的好其實可以很享受,大家都是一起學習的過程,不存在誰為難誰。下面說說我覺得架構評審(非代碼評審)中看重的需要評審的一些點。
組件選型
· 為什麼選A不選B呢?
· A不是開源的,出了問題怎麼辦?
· B雖然是開源的,但是是Erlang寫的,公司沒人能看懂怎麼辦?
· C我看待解決的Issues還有很多,有沒有去了解過?
· 這個組件在性能方面你是否瞭解過?
· 開源的免費版本不支持集群怎麼辦?
· 如果徹底要自己寫這個組件有沒有可能性?
組件特別是存儲組件選型挺重要的,真心建議事先可以有那麼幾周的時間搭一個高可用的集群,使用接近於真實的數據對組件進行壓測(你看之前我博客上的Mongodb的壓測文章停火的,說明很多人沒有這個時間和條件對一些組件進行壓測)。眼見為實耳聽為虛,自己通過壓測對比一下自己得出的數據和公開的數據是否有差異,如果有的話說不定還能發現自己使用上的一些問題。儘量還是選用使用的人多的開源組件吧,出了問題至少Patch不會來的太慢。
性能
· 我們需求的TPS、QPS和RT是多少?
· 整體設計上會做到的TPS、QPS和RT是多少?
· 隨著數據量的增大系統性能會不會出現明顯問題?
· 系統哪個環節會是最大的瓶頸?
· 是否打算做壓力測試,壓力測試方案是怎麼樣的?
· 怎麼提高前端用戶的訪問流暢性?
對於重要的項目,建議做一下整體壓測,沒有經過壓測得出來的估計的結論往往可能是錯的,我們總以為最終會死在最後的存儲上,但是很可能早早就死在了程序的低級錯誤上,比如在一些存儲組件的Client使用上,如果沒把控好最佳實踐(把應該作為單例使用Clinet每次都去創建一次,默認的線程數小的可憐應該重新配置但是保留了默認值),死的非常難看。
可伸縮性
· 每一個環節是否都是可以橫向擴展的?
· 擴容需要怎麼做手動還是自動?
· 數據庫不能橫向擴展怎麼辦?
· 縱向擴展有多少效果?
· 橫向擴展是否是線性的?
· 擴展後是否可以提高響應速度?
靈活性
· 是否有了解過產品層面以後會怎麼發展?
· 模塊A是否能拆分出去獨立為其它業務服務?
· 模塊B是否可以替換為另一種第三方數據源?
· 如果流程有變,需要多大的工作量來適應?
· 業務是否可以做到可配?
可擴展性
· 為什麼A和B都有差不多的邏輯?
· 是否考慮到了A業務的實現以後還有B的可能性?
· 如果現在有兩種策略以後擴展到了八種策略怎麼做?
· 以後是否可以把這個業務的H5前端適配到PC?
可靠性
· 是否架構中有單點?
· 故障轉移是怎麼實現的?
· 集群內部故障轉移需要多久?
· MQ或存儲出現問題的時候系統會怎麼樣?
· MQ或存儲出現問題又恢復了系統是否會自己恢復?
· 是否考慮過異地故障轉移的方案?
· 是否考慮過多活的方案?
· 是否有數據丟失的可能性?
· 數據丟失後是否可以恢復?
· 系統徹底掛了對其它業務的影響是什麼?
· 系統徹底掛了是否可以有線下的方式走業務?
安全性
· 是否徹底避免SQL注入和XSS?
· 是否做了風控策略?
· 是否有防刷保護機制?
· 數據庫拖庫了會怎麼樣?
· 是否有數據洩露的可能性?
· 數據的權限怎麼控制的?
· 功能的權限是怎麼控制的?
· 是否做了日誌審計?
· 受到了DDOS攻擊怎麼辦?
· 數據傳輸是否加密驗籤?
兼容性
· 老的系統打算怎麼辦?
· 怎麼進行新老系統替換?
· 新老系統能否來回切換?
· 別的系統怎麼連接你這套新服務?
· 上下游依賴是否梳理過,影響範圍多大?
· 上下游改造的難度怎麼樣?
· 上下游改造有排期嗎?
· 上下游改造的計劃和通知時間確定了嗎?
· 使用了新的數據源數據怎麼遷移?
· 使用了新的技術老項目開發能否適應?
彈性處理
· 這個數據重複消費會怎麼樣?
· 這個接口重複調用會怎麼樣?
· 是否考慮了服務降級?哪些業務支持降級?
· 是否考慮了服務熔斷?熔斷後怎麼處理?
· 是否考慮了服務限流?限流後客戶端表現怎麼樣?
· 隊列爆倉會怎麼樣?
· 是否考慮了隔離性?
事務性
· 這段業務由誰保證事務性?
· 數據庫事務回滾後會怎麼樣?
· 服務調用了失敗怎麼辦?
· 隊列補償怎麼做的?
· 服務調用補償怎麼做的?
· 數據補償實現最終一致需要多久?
· 在數據不完整的時候用戶會感知到嗎?
可測試性
· 測試環境和線上的差異多大?
· 是否支持部署多套隔離的測試環境?
· 是否打算做單元測試,覆蓋率目標是多少?
· 測試黑盒白盒工作量的比例是怎麼樣的?
· 是否支持接口層面的自動化測試?
· 是否有可能做UI自動化測試?
· 壓測怎麼造數據?
· 是否可以在線上做壓測?
· 線上壓測怎麼隔離測試數據?
· 是否有測試白名單功能?
可運維性
· 每一個組件對服務器哪方面的壓力會最大?
· 重新搭建整套系統最快需要多少時間?
· 系統是否可以完全基於源代碼構建?
· 系統是否有初始化或預熱的環節?
· 系統裡哪些環節需要人工參與?
· 數據是否需要定期歸檔處理?
· 會不會有突發的數據量業務量增大?
· 隨著時間的推移如果壓力保持不變的話系統需要怎麼來巡檢和維護?
· 怎麼在容器裡進行部署?
監控
· 業務層面哪些指標需要監控和報警?
· 應用層面系統內部是否有暴露了一些指標作監控和報警?
· 系統層面使用的中間件和存儲是否有監控報警?
· 是否所有環節都接入了全鏈路跟蹤?
· 出現報警的時候應該由誰來處理?
· 每一個模塊是否有固定的主要和次要負責人?
· 有沒有可能系統出了問題無法通過監控指標體現?
· 哪些指標需要上大屏由監控進行7*24監控?
看了這麼多問題可能會覺得這架構設計是沒法做了,其實不同階段的項目有不同的目標,我們不會在項目起步的時候做99.99%的可用性支持百萬QPS的架構,高效完成項目的業務目標也是架構考慮的因素之一。而且隨著項目的發展,隨著公司中間件和容器的標準化,很多架構的工作被標準化替代,業務代碼需要考慮架構方面伸縮性運維性等等的需求越來越少,慢慢的這些工作都能由架構和運維團隊來接。一開始的時候我們可以花一點時間來考慮這些問題,但是不是所有的問題都需要有最終的方案。
第二部分:技術設計文檔五要素
如果你在Google搜索架構設計文檔、技術設計文檔、概要設計文檔可以搜索到很多模板,很多公司也會以這些模板作為設計文檔的模板來讓大家填寫。對於大部分所謂的項目只是一個項目中的一個小環節是一個具體的業務邏輯,因此總是可以看到大家寫的所謂的技術設計文檔只能填滿文檔的20%,其餘都不知道怎麼寫。當你不知道文檔應該寫哪些內容的時候可以這麼來考慮問題,就是你這個項目接下去是要賣給別人來用的,你沒有機會當面和他把這個項目說清楚,你只能通過文檔來把事情寫清楚,別人就給你一次機會,如果看不懂你文檔表達的意思,不能理解你的項目,你的項目就賣不出去不值錢,這個時候你一定會從各個角度來剖析你的系統想盡一切辦法來把事情說清楚,用這個方法逼一下自己的,你的文檔會很優秀。接下去我想說一下如果是我的話我看重技術設計的哪些部分以及這些部分的文檔的寫作方式,這些內容構成了一個必要的(概要)設計文檔,算是拋磚引玉。
交代背景和需求全貌
在這裡,推薦使用腦圖在技術角度給出一下自己理解的項目需求的分佈。PRD中的產品功能腦圖可以和這裡技術角度的腦圖有差異,在說清楚需求的同時側重技術層面,體現在:
· 可以不按照需求的功能點進行歸類而是按照實際項目歸類,把需求列在實際的項目下面
· 可以區分需求是自己乾的還是調用外部的接口,可以在圖上以不同的形態提現
· 可以畫出功能之間的依賴關係,以虛線實線進一步區分依賴的程度
· 可以在圖上體現需求的優先級以及需求目前的進展和負責人,這樣基本一個圖就可以看清楚這個項目需要消耗多少資源需要多久可以結束
看了這個圖基本產品需求就可以理解個大概,具體的細節規則可以進一步參考PRD。
系統架構圖
在本系列文章的第二到第五篇中,我都配了一個架構圖。架構圖需要傳遞清楚下面的信息:
· 項目由哪些模塊、服務、緩存、存儲構成,可以以不同的圖案和顏色代表不同類型
· 模塊之間的依賴關係(當然,也可以從數據的流向角度來畫)
· 核心流程的步驟,沿著圖上的1、2、3基本就可以大概瞭解核心流程的實現
· 可以用大的框把組件進行分組來描述組件的部署方式(比如相同機器上承載的組件在一個框內)
· 可以以邊框的虛實來分類項目內的組件或三方組件,可以以箭頭的虛實來標記主要流程次要流程等等
UML裡會有一些具體的分類,什麼類圖、組件圖、部署圖等等,我覺得不必拘泥於這些細節,通過線線框框的架構圖能把模塊和模塊之間的關係表述請求,然後再配以一定的文字來說明每一個組件即可。我自己常用的是gliffy,只要能說清楚,Word畫也可以。根據項目的大小,圖上的模塊不一定是需要獨立部署的進程,模塊也可以是項目內部的一個模塊或類。對於複雜的項目,要畫一個圖說清楚很難,可以畫一個大的架構圖,然後針對每一個模塊或流程再細化畫不同層次的圖。
對外API定義
API的詳細定義可以由Swagger UI、Spring REST Doc、Miredot等等工具生成,這些生成的接口是按照代碼來組織層次關係的,只能體現接口的參數定義不能體現接口的形態等,是沒有思想的,不適合用來閱讀,只適合用來參考。因此還是建議做一個腦圖來總體闡述一下接口的:
· 分類,按業務功能的分類,按受眾的分類等等
· 形式(圖上不同的顏色),同步還是異步(結果不在響應中,單獨的回調返回),單條還是批量,數據接口還是頁面調用等等
· 重要性(圖上文字後的星號),比如重點標記主流程的接口
圖上可以不顯示出參數清單,但可以以簡單的文字來描述重要參數,比如下單接口:->@用戶身份,優惠券ID*,[{商品ID,數量}]代表輸入,
之前強調過好多次涉及到和外部交互的API是設計中非常重要的一個環節,不僅僅體現了系統對外輸出的能力,也體現了系統設計在安全性、複用性、封裝等方面的平衡。
交互時序
時序圖的表達非常重要,可以表現需求腦圖、架構圖和API腦圖無法表現出來的幾個方面,清晰展現了某個事情:
· 關鍵的利益關係方。這個事情由哪幾個方面構成,可以是用戶、甲方、乙方這麼來分,也可以是用戶、APP客戶端、服務端這麼來分
· 每一方在做什麼,依賴的又是什麼,整個順序是怎麼樣的
· 技術層面這是同步接口、還是回調、還是非技術的線下流程
· 還可以在圖上表現出可選邏輯,條件判斷邏輯,循環邏輯等等
我覺得能在比較高的層面說一下技術(對接)流程即可,不一定要詳細到類和類之間的交互,類和類之間的交互閱讀代碼或直接看全鏈路調用的圖就可以。如果項目有多個合作方多個依賴方,項目流程比較複雜,那麼序列圖是能把這個事情說清楚的最好的方式。
對於這種時序圖,採用傳統的工具來畫費時費力,推薦下面兩個工具(和),可以在幾分鐘內生成需要的圖。
我們輸入類似的文字:
title 合作流程
用戶->XX:投資YY標的
XX->YY:同步投資情況,更新可用額度
用戶->YY:在額度內消費
YY->XX:同步消費情況,更新可用額度,更新回款計劃
YY->XX:還款
XX->用戶:回款(已消費部分作為手續費給XX)
opt 線下流程
XX->YY:對於YY用戶的消費出賬單
YY->XX:對賬確認賬單
XX->YY:打款開具發票
End
網站生成類似的時序圖,還可以自由選擇自己喜歡的樣式:
數據庫ER
ER圖就是實體聯繫圖。形式上我們可以在圖上表現幾個點:
· 實體:哪些表
· 實體上的屬性:體現實體之間關係以及實體業務功能的重要字段
· 聯繫:實體和實體之間的關係,比如一對多,多對一還是多對多之類
在有的時候我們可以省略屬性的類型定義,甚至可以直接省略具體的屬性(實體名和M對N的關係是必須的),把圖簡化為類似下面的部分:
ER圖的信息量非常大,絕對不是粘貼一下表結構的DDL可以替代的,原因是:
· ER圖可以以極小的空間展現很多信息,這樣我們可以在圖上對業務進行分組,看到全貌
· ER圖展現的是表和表之間的關係,一眼可以看出最重要核心的表是哪些
比如下圖,是否一眼就可以看明白一套P2P金融業務整個數據結構的架構呢:
(隨便畫的圖,不代表任何意義,請不要以這個圖做P2P的表結構設計)
所有的圖,文字只是一個維度,我們要學會利用邊框類型(矩形、圓角矩形),邊框樣式(虛線,實線),填充色,文字顏色,關聯線條粗細顏色樣式,框內ICON來增加我們要表現信息的維度,最多可以增加到6維+,這種能力是文字很難實現的。一圖勝過千言,所以我一直認為圖是設計文檔中非常重要的部分。
其它
之前我說了我們可以以五圖的形式(需求腦圖、架構圖、API腦圖、序列圖、數據庫ER圖)把系統大概介紹一個底朝天,說清楚了需求、架構、對外接口、交互流程和數據結構設計這幾個事情,業務項目說清楚這些足夠了。
對於偏向於中間件(不管是基礎中間件還是業務中間件,中臺)的項目(而不是業務項目),這裡我再補充幾個重要的方面,需要在設計文檔中有體現:
· 可靠性:是否有單點的組件,非單點的組件如何做故障轉移
· 高性能:是否有抗突發性能壓力的能力,大概可以滿足多少的TPS和QPS,怎麼去做來實現高性能
· 可擴展:隨著壓力上升哪些環節可以做擴展,怎麼做擴展
· 安全性:哪些手段防突破,萬一突破了後果怎麼樣
· 兼容性:和遺留系統怎麼通訊,怎麼做遷移
· …………等等方面
這些點我就不一一展開說了,在第一節說架構評審的時候都有提到過,針對那些問題寫一下自己的設計是怎麼應對的吧。
這些點我認為可以構成一個合格的設計文檔,文檔的形式不重要,重要的是可以把業務的技術實現梳理清楚,確保我們在開發之前有一個清晰的思路,在開發上線後,文檔也是一個後人熟悉系統的非常重要的手段。你可能會提出疑問說這樣的設計文檔是不是太粗略了一點,完全沒有體現到軟件層面設計的細節,沒錯是這樣,但是我一直說的是互聯網架構心得,敢問現在互聯網項目從0開始的大項目1到2個月上線,大的版本迭代2週一次,如果設計的時間是五分之一的話,設計也就是2天到一週這樣子,我們有多少時間和能力來細化文檔呢,如果能把我這裡說的五要素都做好,對於互聯網項目已經笑死。
還有一點往往會比較可惜,我們或許可以做到在開發之前有一個概要設計文檔的產出,但是我們很難做到在系統上線後隨著迭代還能繼續維護第一版產品上線時那個大而全的文檔。隨著產品的迭代,我們的技術文檔也像PRD迭代文檔一樣只說這次迭代的技術改動的話,這種設計文檔因為沒有全局觀意義不大。對於這個情況,我覺得對於每一條業務線的產品,我都建議我們至少能維護大而全的下面這些文檔的全量版本:
· 完整表結構(順帶標一下歸檔方案、重要程度)
· 需求全貌
· 對外產品能力輸出全貌
· 整體架構圖
· 關鍵業務交互流程(特別是那種很難說清楚的多方結算關係)
定期回顧一下這五個文檔,根據最近的需求改改,可能也只需要花費幾小時的時間,對於大項目其意義往往是新人的靈魂導師(之前我有畫過一個比較複雜系統的架構圖,這個架構圖我看到有人做了桌面)。
閱讀更多 隨緣主人的園子 的文章