在文章《如何識(shí)別和定位架構(gòu)問題》中慷暂,我描述了如何識(shí)別架構(gòu)中已經(jīng)存在的問題。文章重點(diǎn)關(guān)注在組件的邊界以及組件之間的關(guān)系上,這部分在架構(gòu)中非常重要舍哄,一旦有問題,都會(huì)是比較嚴(yán)重的問題。
除此之外,是不是還有其他的問題依然需要優(yōu)化呢立镶?答案是肯定的,架構(gòu)優(yōu)化的目標(biāo)是為了提升系統(tǒng)的可用性和可擴(kuò)展性类早,減少線上問題媚媒,進(jìn)而提升用戶體驗(yàn)。因此莺奔,只要是能夠幫助達(dá)成這個(gè)目標(biāo)欣范,都可以納入架構(gòu)優(yōu)化中变泄。在這篇文章中令哟,我們就展開討論架構(gòu)優(yōu)化的幾個(gè)方向恼琼。
從技術(shù)層面來說,架構(gòu)優(yōu)化要解決的就是系統(tǒng)中的不良設(shè)計(jì)屏富,寬泛來說都可以歸結(jié)為技術(shù)債晴竞。在《技術(shù)債的前世今生》中我從技術(shù)債產(chǎn)生原因的角度討論了技術(shù)債分類,但并沒有針對(duì)技術(shù)債的內(nèi)容進(jìn)行分類狠半,在2014年Nicolli S.R. Alves等發(fā)表的論文《Towards an Ontology of Technical Debt》中噩死,定義了13種技術(shù)債類型:
圖片來源:論文《Towards an Ontology of Terms on Technical Debt》中 Fig. 2
Dwarak Govind Parthiban在論文《Examination of tools for managing different dimensions of Technical Debt》 中將技術(shù)債維度定義為:
圖片來源:論文《Examination of tools for managing different dimensions of Technical Debt》中 TABLE IV
本文中主要關(guān)注技術(shù)設(shè)計(jì)和實(shí)現(xiàn)層面需要優(yōu)化的內(nèi)容,不考慮組織神年、人員以及流程等方面的問題已维,也暫時(shí)不討論測(cè)試、已知Defect以及文檔相關(guān)的債務(wù)已日,雖然這些債務(wù)也很重要垛耳。結(jié)合以上兩篇論文,從架構(gòu)的不同維度飘千,我們可以將架構(gòu)優(yōu)化的重點(diǎn)放在以下四個(gè)方向:代碼實(shí)現(xiàn)(Code Debt)堂鲜、組件設(shè)計(jì)(Design Debt)、架構(gòu)設(shè)計(jì)(Architecture debt)和基礎(chǔ)設(shè)施(Infrastructure Debt)护奈。
代碼實(shí)現(xiàn)(Code Debt)
代碼實(shí)現(xiàn)債務(wù)指在開發(fā)過程中缔莲,沒有遵守相關(guān)的規(guī)范產(chǎn)生的問題,這些問題會(huì)對(duì)代碼的可讀性和可測(cè)試性產(chǎn)生很大影響霉旗。另外很多細(xì)節(jié)的設(shè)計(jì)不合理也會(huì)帶來非常嚴(yán)重的穩(wěn)定性問題痴奏,舉兩個(gè)例子:
- 大量無效的日志輸出,占用磁盤資源厌秒,極端情況下會(huì)出現(xiàn)因磁盤容量不足導(dǎo)致線上故障
- 循環(huán)中進(jìn)行數(shù)據(jù)庫或集成接口的調(diào)用读拆,這種接口的性能在請(qǐng)求數(shù)據(jù)量較大時(shí)影響非常嚴(yán)重,對(duì)數(shù)據(jù)庫和集成的服務(wù)產(chǎn)生非常大的壓力简僧,進(jìn)而影響系統(tǒng)的穩(wěn)定性
通常建椰,代碼的問題可以通過源代碼掃描工具來識(shí)別,比如PMD岛马、ESLint棉姐、CheckStyle、Sonaqube等啦逆。但類似日志或循環(huán)中進(jìn)行數(shù)據(jù)庫讀寫這種問題很難通過自動(dòng)化工具識(shí)別伞矩,針對(duì)這些場(chǎng)景,可以通過CodeReview夏志,定期的日志分析乃坤,Tracing數(shù)據(jù)的分析等方式來識(shí)別。
組件設(shè)計(jì)(Design Debt)
這里的組件設(shè)計(jì)指的是架構(gòu)中一個(gè)組件(比如一個(gè)微服務(wù))的內(nèi)部設(shè)計(jì),組件內(nèi)部的設(shè)計(jì)可以有很多種(比如分層架構(gòu)湿诊、六邊形架構(gòu)等)狱杰,但不管如何劃分一個(gè)組件內(nèi)部的模塊,在實(shí)際開發(fā)過程中厅须,想做到完全符合設(shè)計(jì)預(yù)期都是很難甚至無法完成的事情仿畸。因此,一定會(huì)產(chǎn)生很多因設(shè)計(jì)不合理導(dǎo)致的技術(shù)債朗和,比如:
- 封裝不足错沽,每個(gè)服務(wù)都有類似的功能,但有各自的實(shí)現(xiàn)眶拉,不完全統(tǒng)一
- 過度封裝千埃,比如使用common包這樣的公共依賴,希望用大而全的共享庫解決問題忆植,然而實(shí)踐中會(huì)產(chǎn)生各種版本沖突問題放可,參見《消滅微服務(wù)的壞味道 之 共享庫》
- 違反SOLID原則的設(shè)計(jì),超大API或者超大的類
架構(gòu)設(shè)計(jì)(Architecture debt)
架構(gòu)設(shè)計(jì)債務(wù)主要指在軟件整體架構(gòu)上存在的問題唱逢,典型的如微服務(wù)邊界劃分不合理吴侦,職責(zé)不清。
然而坞古,這種問題很難快速識(shí)別备韧,也很難通過簡單的代碼修改來償還。這通常需要對(duì)業(yè)務(wù)和架構(gòu)有深刻的理解痪枫,并輔助以一些工具和實(shí)踐方法(如DDD或8X Flow等建模分析方法)织堂。可以參考《如何識(shí)別和定位架構(gòu)問題》文中對(duì)架構(gòu)組件邊界和集成方式的分析方法奶陈。
架構(gòu)設(shè)計(jì)債務(wù)產(chǎn)出的方案重點(diǎn)關(guān)注在因職責(zé)不清易阳,交互方式不合理導(dǎo)致的問題,可能有以下幾種(以微服務(wù)架構(gòu)為例):
- 微服務(wù)的拆分或合并
- 微服務(wù)間集成方式的優(yōu)化(同步調(diào)用或異步事件)
- 第三方集成策略的優(yōu)化(識(shí)別業(yè)務(wù)主體吃粒,根據(jù)交互實(shí)時(shí)性要求調(diào)整集成策略)
基礎(chǔ)設(shè)施(Infrastructure Debt)
軟件系統(tǒng)的基礎(chǔ)設(shè)施可以分為兩大類:
- 軟件運(yùn)行的環(huán)境以及相關(guān)的基礎(chǔ)設(shè)施依賴潦俺,如VM、數(shù)據(jù)庫徐勃、緩存等
- 軟件開發(fā)過程中依賴的一些基礎(chǔ)框架
- 技術(shù)框架的選型事示,如Java、React僻肖、Spark等
- 依賴的開源軟件肖爵,如log4j等
- 自封裝的基礎(chǔ)設(shè)施包,比如日志處理臀脏、數(shù)據(jù)源管理劝堪、秘鑰管理等
基礎(chǔ)設(shè)施承載了整個(gè)軟件的運(yùn)行環(huán)境冀自,一旦有問題,也是影響最嚴(yán)重的秒啦,比如VM出了問題熬粗,所有部署在這個(gè)VM上的服務(wù)都會(huì)受到影響,再比如框架代碼一旦發(fā)現(xiàn)漏洞帝蒿,影響的也將是所有的服務(wù)荐糜。
以上四個(gè)方向巷怜,從上到下范圍逐漸變大葛超,產(chǎn)生的影響也逐漸變大,因此通常情況下延塑,在識(shí)別到問題后绣张,處理優(yōu)先級(jí)應(yīng)該是反過來,先從基礎(chǔ)設(shè)施開始关带,最后是代碼實(shí)現(xiàn)侥涵。然而,真正操作過程中宋雏,還要根據(jù)問題的嚴(yán)重程度以及開發(fā)的投入產(chǎn)出比作為額外的信息芜飘,來輔助優(yōu)先級(jí)排序。