《軟件架構(gòu)基礎(chǔ)(Fundamentals of Software Architecture)》被譽(yù)為和《設(shè)計(jì)數(shù)據(jù)密集型應(yīng)用》一樣經(jīng)典的后端書籍,架構(gòu)師的入門指南。本篇為該書第一章的讀書筆記,2021 年第一個(gè)目標(biāo)就是和大家一起讀完這本書。 如今,全球范圍內(nèi)“架構(gòu)師”這一頭銜炒得十分火熱,但沒有真正的指南來幫助開發(fā)人員成為軟件架構(gòu)師。這本書就是一本架構(gòu)師指南。 歡迎關(guān)注我的公眾號:“多顆糖”。
1. 什么是軟件架構(gòu)學(xué)習(xí)架構(gòu)就像學(xué)習(xí)藝術(shù)一樣,讀者必須要在特定的背景下去理解它。 在一個(gè)動態(tài)系統(tǒng)中,不存在一勞永逸的解決方案。 學(xué)習(xí)架構(gòu)時(shí),必須放在上下文中理解。架構(gòu)師做的許多決定都是基于他們所處的實(shí)際情況。
整個(gè)行業(yè)都在努力精確定義“軟件架構(gòu)”,有些稱為系統(tǒng)的藍(lán)圖,有些定義為開發(fā)的路線圖。本書關(guān)于架構(gòu)的定義主要從四個(gè)方面:
系統(tǒng)的結(jié)構(gòu)指的是系統(tǒng)實(shí)現(xiàn)架構(gòu)風(fēng)格的類型(如微服務(wù)、分層或微內(nèi)核)。但僅僅通過結(jié)構(gòu)來描述一個(gè)架構(gòu),并不能完全闡明一個(gè)架構(gòu)。架構(gòu)特性多以 "-ility" 結(jié)尾(例如 Availability、Scalability)架構(gòu)決策定義了系統(tǒng)應(yīng)該如何構(gòu)建的規(guī)則。例如,架構(gòu)師可能會做出一個(gè)架構(gòu)決策,即在分層架構(gòu)中只有業(yè)務(wù)層和服務(wù)層可以訪問數(shù)據(jù)庫(見圖),限制表現(xiàn)層直接調(diào)用數(shù)據(jù)庫。架構(gòu)決策形成了系統(tǒng)的約束,并指導(dǎo)開發(fā)團(tuán)隊(duì)什么是允許的,什么是不允許的。設(shè)計(jì)原則與架構(gòu)決策的不同之處在于,設(shè)計(jì)原則是一個(gè)指導(dǎo)方針,而不是一個(gè)硬性規(guī)定。例如,圖示的設(shè)計(jì)原則指出,開發(fā)團(tuán)隊(duì)?wèi)?yīng)該在微服務(wù)架構(gòu)中的服務(wù)之間傳遞異步消息來提高性能。一個(gè)架構(gòu)決策永遠(yuǎn)不可能涵蓋服務(wù)之間通信的每一個(gè)條件和選項(xiàng),設(shè)計(jì)原則為首選方法(在本例中,異步消息傳遞)提供指導(dǎo),允許開發(fā)人員在特定情況下選擇更合適的通信協(xié)議(如 REST 或 gRPC)。2. 架構(gòu)師的 8 大核心能力2.1 做出架構(gòu)決定架構(gòu)師應(yīng)確定架構(gòu)和設(shè)計(jì)原則,用于指導(dǎo)團(tuán)隊(duì)、部門或整個(gè)企業(yè)的技術(shù)決策。 架構(gòu)師應(yīng)該指導(dǎo)而不是指定技術(shù)選擇。例如,架構(gòu)師應(yīng)該決定開發(fā)團(tuán)隊(duì)使用基于響應(yīng)式 (Reactive) 的框架進(jìn)行開發(fā),從而指導(dǎo)開發(fā)團(tuán)隊(duì)在 Angular、Elm、React.js、Vue 或其他任何基于響應(yīng)式的 Web 框架之間做出選擇。 架構(gòu)師偶爾需要做出特定的技術(shù)決策,以保留特定的架構(gòu)特性,如可擴(kuò)展性、性能或可用性。 架構(gòu)師經(jīng)常為找到正確的界線而苦惱。 2.2 持續(xù)分析架構(gòu)多數(shù)架構(gòu)都會經(jīng)歷結(jié)構(gòu)性衰變,當(dāng)開發(fā)人員進(jìn)行編碼或設(shè)計(jì)變更時(shí),會影響到所需的架構(gòu)特性,如性能、可用性和可擴(kuò)展性。架構(gòu)師需要評估三年或更長時(shí)間前定義的架構(gòu)在今天的可行性。 另一方面,架構(gòu)師還常常忘記測試和發(fā)布環(huán)境。敏捷性有很大的好處,如果團(tuán)隊(duì)需要幾周的時(shí)間來測試變更,而發(fā)布又需要幾個(gè)月的時(shí)間,那么架構(gòu)師就無法實(shí)現(xiàn)整體架構(gòu)的敏捷性。 2.3 緊跟最新趨勢架構(gòu)師要跟上最新的技術(shù)和行業(yè)趨勢。 開發(fā)人員必須掌握他們每天使用的最新技術(shù),以保持代碼能力(并保住一份工作!)。架構(gòu)師有一個(gè)更關(guān)鍵的要求,就是要掌握最新的技術(shù)和行業(yè)趨勢。架構(gòu)師所做的決定往往是長期的,難以改變的,了解和跟蹤關(guān)鍵趨勢有助于架構(gòu)師為未來做好準(zhǔn)備,做出正確的決定。 2.4 確保遵守各項(xiàng)決定架構(gòu)師要不斷驗(yàn)證開發(fā)團(tuán)隊(duì)是否遵循架構(gòu)師定義、記錄和傳達(dá)的架構(gòu)決策和設(shè)計(jì)原則。
2.5 多樣化的接觸和經(jīng)驗(yàn)架構(gòu)師要接觸多種多樣的技術(shù)、框架、平臺和環(huán)境。 現(xiàn)在的大多數(shù)環(huán)境都是異構(gòu)的,一個(gè)架構(gòu)師至少應(yīng)該知道如何與多個(gè)系統(tǒng)和服務(wù)對接,不管這些系統(tǒng)或服務(wù)是用什么語言、平臺和技術(shù)編寫的。 最好方法之一是讓架構(gòu)師延伸自己的舒適區(qū),只關(guān)注單一技術(shù)或平臺是一個(gè)安全的避風(fēng)港,一個(gè)好的軟件架構(gòu)師應(yīng)該積極尋找機(jī)會,以獲得多種語言、平臺和技術(shù)的經(jīng)驗(yàn),關(guān)注技術(shù)廣度而不只是技術(shù)深度。 2.6 具備業(yè)務(wù)領(lǐng)域知識一個(gè)架構(gòu)師要有一定的業(yè)務(wù)領(lǐng)域?qū)I(yè)知識。 有效的軟件架構(gòu)師不僅了解技術(shù),還了解業(yè)務(wù)問題。如果沒有業(yè)務(wù)領(lǐng)域的知識,就很難理解業(yè)務(wù)問題、目標(biāo)和需求,很難設(shè)計(jì)出滿足業(yè)務(wù)需求的有效架構(gòu)。 最成功的架構(gòu)師是那些擁有廣泛的、實(shí)踐性的技術(shù)知識,再加上對某一特定領(lǐng)域的深刻了解的人。這些軟件架構(gòu)師能夠使用這些利益相關(guān)者所能理解的領(lǐng)域知識和語言,與主管和業(yè)務(wù)用戶進(jìn)行有效的溝通。 2.7 具備人際交往能力架構(gòu)師應(yīng)具備卓越的人際交往能力,包括團(tuán)隊(duì)合作、促進(jìn)和領(lǐng)導(dǎo)能力。 擁有卓越的領(lǐng)導(dǎo)力和人際交往能力是大多數(shù)開發(fā)人員和架構(gòu)師難以企及的期望。作為技術(shù)專家,開發(fā)人員和架構(gòu)師喜歡解決技術(shù)問題,而不是人的問題。 架構(gòu)師不僅要為團(tuán)隊(duì)提供技術(shù)指導(dǎo),還要帶領(lǐng)開發(fā)團(tuán)隊(duì)完成架構(gòu)的實(shí)施。無論架構(gòu)師的角色和頭銜是什么,領(lǐng)導(dǎo)能力是成為一個(gè)軟件架構(gòu)師不可或缺的。 2.8 理解和駕馭企業(yè)政治架構(gòu)師要了解企業(yè)的政治氛圍,并能駕馭政治。 在一本關(guān)于軟件架構(gòu)的書中談?wù)撜勁泻婉{馭辦公室政治,可能看起來比較奇怪。主要的一點(diǎn)是,幾乎架構(gòu)師的每一個(gè)決策都會受到挑戰(zhàn)。由于涉及到成本或工作量(時(shí)間)的增加,架構(gòu)決策會受到產(chǎn)品、項(xiàng)目經(jīng)理、開發(fā)和業(yè)務(wù)利益相關(guān)者的挑戰(zhàn),因?yàn)樗麄冇X得自己的方法更好。無論在哪種情況下,架構(gòu)師都必須駕馭公司的政治,并應(yīng)用基本的談判技巧來獲得批準(zhǔn)。 架構(gòu)師不像開發(fā),可以自行設(shè)計(jì)代碼結(jié)構(gòu)、類、設(shè)計(jì)模式甚至是語言而不需要批準(zhǔn),架構(gòu)師做出廣泛而重要的決策,必須為幾乎每一個(gè)決策進(jìn)行論證和爭取。 3. 架構(gòu)師和其它的交集3.1 工程實(shí)踐將軟件開發(fā)過程與軟件工程實(shí)踐分開是有益的。所謂過程,我們指的是如何組建和管理團(tuán)隊(duì),如何進(jìn)行會議以及工作流組織,指的是人們?nèi)绾谓M織和互動的機(jī)制。而**軟件工程實(shí)踐則是指那些已經(jīng)說明了的、可重復(fù)效益的與過程無關(guān)的實(shí)踐。**例如,持續(xù)集成是一種經(jīng)過驗(yàn)證的工程實(shí)踐,它不依賴于特定的過程。 注重工程實(shí)踐很重要:
unknown unknowns 是軟件系統(tǒng)的克星:沒有人知道會出現(xiàn)的東西,卻又意外地出現(xiàn)了。例如:某個(gè)意外的 bug 出現(xiàn)。
迭代流程更符合軟件架構(gòu)的本質(zhì),試圖使用像瀑布這樣的陳舊流程來構(gòu)建微服務(wù)這樣的現(xiàn)代系統(tǒng)的團(tuán)隊(duì)會發(fā)現(xiàn),一個(gè)陳舊的流程忽視了軟件如何結(jié)合在一起的現(xiàn)實(shí),會產(chǎn)生大量的摩擦。 如圖所示,軟件系統(tǒng)的架構(gòu)由需求和所有其他架構(gòu)特征組成。 采用敏捷工程實(shí)踐,如持續(xù)集成、自動機(jī)器供應(yīng)和類似的實(shí)踐,使構(gòu)建彈性架構(gòu)變得更容易。這也說明了架構(gòu)與工程實(shí)踐是如何相互交織在一起的。 3.2 運(yùn)維/DevOps架構(gòu)和相關(guān)領(lǐng)域之間最近最明顯的交集發(fā)生在 DevOps 的出現(xiàn)。許多公司認(rèn)為運(yùn)維是與軟件開發(fā)是分離的,在 20 世紀(jì) 90 年代和 2000 年代設(shè)計(jì)的架構(gòu)都假設(shè)架構(gòu)師無法控制運(yùn)維,架構(gòu)師們被迫圍繞引入的限制進(jìn)行防御性設(shè)計(jì)。因此,他們構(gòu)建了能夠在內(nèi)部處理規(guī)模、性能、彈性和其他一系列能力的架構(gòu)。這種設(shè)計(jì)的副作用是大大增加了架構(gòu)的復(fù)雜性。 微服務(wù)風(fēng)格架構(gòu)的構(gòu)建者們意識到,通過在架構(gòu)和運(yùn)維之間建立一個(gè)聯(lián)絡(luò)點(diǎn),架構(gòu)師可以簡化設(shè)計(jì),依靠運(yùn)維來處理他們最擅長的事情。因此,意識到資源的挪用導(dǎo)致了意外的復(fù)雜性,架構(gòu)師和運(yùn)維合作創(chuàng)建了微服務(wù)。 3.3 流程軟件架構(gòu)與軟件開發(fā)過程大多是正交的(相互不可替代的),大多數(shù)關(guān)于軟件架構(gòu)的書籍都忽略了軟件開發(fā)過程。例如,在過去的幾十年里,由于軟件的性質(zhì),許多公司都采用了敏捷開發(fā)方法。架構(gòu)師在敏捷項(xiàng)目中得到更快的反饋,這使得架構(gòu)師可以更積極地進(jìn)行實(shí)驗(yàn)。 所有的架構(gòu)都會變成迭代式的,這只是時(shí)間問題。為此,我們要在整個(gè)過程中假設(shè)敏捷方法論的基線,并允許適當(dāng)?shù)睦?。例如,許多單體架構(gòu)因?yàn)槟挲g、政治或其他與軟件無關(guān)的因素而使用舊流程的情況還是很常見的。 3.4 數(shù)據(jù)很大一部分嚴(yán)肅的應(yīng)用程序開發(fā)包括外部數(shù)據(jù)存儲,通常采用關(guān)系型(或越來越多的 NoSQL)數(shù)據(jù)庫的形式。然而,許多關(guān)于軟件架構(gòu)的書籍只對架構(gòu)的這一重要方面進(jìn)行了輕描淡寫的處理。代碼和數(shù)據(jù)具有共生關(guān)系:兩者缺一不可。 4. 軟件架構(gòu)法則軟件架構(gòu)第一定律: 軟件架構(gòu)中的所有東西都是一種權(quán)衡。(Everything in software architecture is a trade-off.) 我們對軟件架構(gòu)的定義超越了結(jié)構(gòu)的范疇,包含了原則、特性等,架構(gòu)的范圍比單純的結(jié)構(gòu)更廣,體現(xiàn)在我們的軟件架構(gòu)第二定律中: 為什么比怎么做更重要。(Why is more important than how.) |
|