《從零開始學架構》筆記——第一部分:概念和基礎
第一章 架構基礎
模組與元件
模組:從邏輯角度拆分,主要目的是職責分離
元件:從物理角度拆分,主要目的是單元複用
框架與架構
框架:元件規範(開發規範),提供基礎功能的產品。
架構:對軟體系統結構的描述
架構設計的目的是什麼?
軟體架構的歷史
- 第一次軟體危機——結構化程式設計登場
2000名程式設計師歷時一年,花費原子彈1/4的投入,生產100w行程式碼。最終以失敗告終。
第二次軟體危機——面對物件
軟體擴充套件能力不足,生產力跟不上硬體和業務的發展。
軟體架構
隨著軟體系統規模增加,當系統由許多部分組成時,整個系統的組織,導致了一系列的新的設計問題。
只有規模較大的軟體系統會面臨軟體架構的問題
- 系統規模龐大,內部耦合嚴重
- 修改和擴充套件困難
- 邏輯複雜,問題難以排查和修復
【人力總會有侷限,當自身的能力不足以應對問題時,除了學習之外,也應該思考是否不是自己的問題,而是問題本身超過了人類的侷限】
架構設計的目的
整個軟體開發的歷史,就是一部與複雜度鬥爭的歷史。
而架構設計的主要目的就是為了解決複雜度帶來的問題。
複雜度來源
高效能
電子管,電晶體到積體電路,複雜度難以估量。但這種複雜度在選擇方面幾乎不用考慮,因為沒有人會去選擇購買電子管計算機。
但是對於不同的出行方式,自行車,公交,火車,高鐵,飛機,出行前我們都會根據距離,費用等略作判斷。時代的背景下,飛機的出現並沒有取代火車,自行車等工具,但從現代計算機的應用來說,電子管已經被淘汰了。
而軟體架構就是在一次旅行中,選擇最高性價比的方案。
在軟體系統中,對高效能需求的複雜度體現在單臺計算機為了高效能帶來的複雜度和多臺計算機叢集為了高效能帶來的複雜度。
單機複雜度
作業系統的多程序,多執行緒,程序通訊,多執行緒併發等等。
Redis採用單程序,Nginx可以用多程序。具體使用需要結合業務來分析。
叢集複雜度
任務分配:使用多臺機器,每臺機器都可以處理完整的業務,但會設計到任務分配器,比如硬體F5,軟體Nginx等等。
隨著機器增多,任務分配器的任務就會加重,成為新的效能瓶頸。這個時候就需要叢集式的任務分配器。
任務分解:將系統拆分成更小的組成部分,部署到不同的伺服器中
任務分配可以突破單臺計算機的瓶頸,但持續的增加機器的效率會越來越低。
任務分解換了一種思路,將系統分解,有針對的擴充套件。
優點:
- 簡單系統更加容易有針對性的優化,排錯
- 可以對單個部分進行擴充套件,有的放矢
問題:
- 系統間呼叫資源消耗
總結:
任務分解和任務分配一樣,有一個度,超過這個度,效能反而下降。
高可用:系統無中斷的執行功能
本質上通過冗餘來實現高可用。
冗餘:就好像買電瓶車,一次買十輛,第一輛被偷了騎第二輛,第二輛被偷了騎第三輛,依次類推。
計算高可用
叢集配置,同時有任務分配的瓶頸
儲存高可用
儲存叢集。但會產生資料傳輸的一致性問題。
可擴充套件(靠經驗)
- 預測變化
- 應對變化
低成本
低成本和高可用,高效能是衝突的。
引入新技術,創造新技術。
安全
第二章 架構設計原則
架構與程式設計的鴻溝:不確定性。
程式設計是確定的,不管採用何種方式,執行結果都是肯定的。
而不同的架構可能會產生相同的結果。
合適原則
合適優於業界領先。
優秀的架構都是在企業當前人力,條件,業務等各種約束下設計出來的。(生搬硬套不可取)
簡單原則
簡單優於複雜。
長城的巨集偉,悉尼歌劇院的藝術感,”複雜“在製造領域代表先進,在建築領域代表領先,但在軟體領域代表問題。
為什麼軟體的複雜會帶來問題???
除了軟體開發的複雜性之外,軟體在投入使用後,需要不斷變化。沒聽說過長城不斷拆了重建吧。
演化原則
演化優於一步到位。
對於建築來說,永恆是主題;而對於軟體來說,變化才是主題。
軟體架構更像是一個人類的進化史:
- 首先,需要適應環境活下來(突然想到了初中歷史書上的山頂洞人)惡劣的環境需要大量的體毛來保持身體的恆溫
- 在不斷的發展中,開始製造工具,開始生火抵抗寒冷
- 再到後來,建房子,用動物皮毛保暖
- 於是體毛漸漸退化,也不再吃生肉
- 生存的方式也從打獵變成更加細分的職業
到如今的網際網路商業繁榮,大腦思考更加複雜的軟體架構
類比軟體架構:
- 首先,設計出來的產品可以滿足當前業務需要
- 之後在實際的應用中迭代,保留優秀設計,剔除無用設計,增加必要設計
最好,當業務發生巨大改變,效能要求更高時,架構要面臨擴充套件,重構;甚至程式碼語言會發生變化,但在演變過程中的經驗,邏輯,設計等會在新的架構中延續。(設計模式強推)
【不要貪大求全,不要盲目照搬大公司的架構】
第三章 架構設計流程
識別複雜度——有針對性
- 分析業務邏輯的複雜性
- 是否有做高效能高可用的成本
優先解決最主要的複雜度問題。
使用成熟技術——設計備選方案
- 備選方案以3-5個為最佳
- 備選方案差異要比較明顯(比如主備方案和叢集方案)
- 備選方案的技術不要侷限已經熟悉的技術(如果你有一把錘子,那麼所有的問題都是釘子)
- 備選方案不用過於詳細(關注技術選型,而不是技術細節)
深思熟慮——評估備選方案
- 效能
- 複雜度和開發時間
- 成本
- 擴充套件
精雕細琢——詳細方案設計
Nginx負載均衡策略的演算法選擇
- 輪詢
- 加權輪詢
- ip_hash