《從零開始學架構》筆記——第一部分:概念和基礎

  • 2019 年 10 月 6 日
  • 筆記

第一章 架構基礎

模塊與組件

模塊:從邏輯角度拆分,主要目的是職責分離

組件:從物理角度拆分,主要目的是單元復用

框架與架構

框架:組件規範(開發規範),提供基礎功能的產品。

架構:對軟件系統結構的描述

架構設計的目的是什麼?

軟件架構的歷史

  • 第一次軟件危機——結構化程序設計登場

2000名程序員歷時一年,花費原子彈1/4的投入,生產100w行代碼。最終以失敗告終。

  • 第二次軟件危機——面對對象 軟件擴展能力不足,生產力跟不上硬件和業務的發展。
  • 軟件架構 隨着軟件系統規模增加,當系統由許多部分組成時,整個系統的組織,導致了一系列的新的設計問題。 只有規模較大的軟件系統會面臨軟件架構的問題
    • 系統規模龐大,內部耦合嚴重
    • 修改和擴展困難
    • 邏輯複雜,問題難以排查和修復

    【人力總會有局限,當自身的能力不足以應對問題時,除了學習之外,也應該思考是否不是自己的問題,而是問題本身超過了人類的局限】

架構設計的目的

整個軟件開發的歷史,就是一部與複雜度鬥爭的歷史。

而架構設計的主要目的就是為了解決複雜度帶來的問題。

複雜度來源

  • 高性能 電子管,晶體管到集成電路,複雜度難以估量。但這種複雜度在選擇方面幾乎不用考慮,因為沒有人會去選擇購買電子管計算機。 但是對於不同的出行方式,單車,公交,火車,高鐵,飛機,出行前我們都會根據距離,費用等略作判斷。時代的背景下,飛機的出現並沒有取代火車,單車等工具,但從現代計算機的應用來說,電子管已經被淘汰了。 而軟件架構就是在一次旅行中,選擇最高性價比的方案。 在軟件系統中,對高性能需求的複雜度體現在單台計算機為了高性能帶來的複雜度多台計算機集群為了高性能帶來的複雜度。
    • 單機複雜度 操作系統的多進程,多線程,進程通信,多線程並發等等。 Redis採用單進程,Nginx可以用多進程。具體使用需要結合業務來分析。
    • 集群複雜度
      • 任務分配:使用多台機器,每台機器都可以處理完整的業務,但會設計到任務分配器,比如硬件F5,軟件Nginx等等。 隨着機器增多,任務分配器的任務就會加重,成為新的性能瓶頸。這個時候就需要集群式的任務分配器。
      • 任務分解:將系統拆分成更小的組成部分,部署到不同的服務器中 任務分配可以突破單台計算機的瓶頸,但持續的增加機器的效率會越來越低。 任務分解換了一種思路,將系統分解,有針對的擴展。 優點
        • 簡單系統更加容易有針對性的優化,排錯
        • 可以對單個部分進行擴展,有的放矢

        問題:

        • 系統間調用資源消耗

        總結: 任務分解和任務分配一樣,有一個度,超過這個度,性能反而下降。

  • 高可用:系統無中斷的執行功能 本質上通過冗餘來實現高可用。 冗餘:就好像買電瓶車,一次買十輛,第一輛被偷了騎第二輛,第二輛被偷了騎第三輛,依次類推。
    • 計算高可用 集群配置,同時有任務分配的瓶頸
    • 存儲高可用 存儲集群。但會產生數據傳輸的一致性問題。
  • 可擴展(靠經驗)
    • 預測變化
    • 應對變化
  • 低成本 低成本和高可用,高性能是衝突的。 引入新技術,創造新技術。
  • 安全

第二章 架構設計原則

架構與編程的鴻溝:不確定性。

編程是確定的,不管採用何種方式,執行結果都是肯定的。

而不同的架構可能會產生相同的結果。

合適原則

合適優於業界領先。

優秀的架構都是在企業當前人力,條件,業務等各種約束下設計出來的。(生搬硬套不可取)

簡單原則

簡單優於複雜。

長城的宏偉,悉尼歌劇院的藝術感,」複雜「在製造領域代表先進,在建築領域代表領先,但在軟件領域代表問題。

為什麼軟件的複雜會帶來問題???

除了軟件開發的複雜性之外,軟件在投入使用後,需要不斷變化。沒聽說過長城不斷拆了重建吧。

演化原則

演化優於一步到位。

對於建築來說,永恆是主題;而對於軟件來說,變化才是主題。

軟件架構更像是一個人類的進化史:

  • 首先,需要適應環境活下來(突然想到了初中歷史書上的山頂洞人)惡劣的環境需要大量的體毛來保持身體的恆溫
  • 在不斷的發展中,開始製造工具,開始生火抵抗寒冷
  • 再到後來,建房子,用動物皮毛保暖
  • 於是體毛漸漸退化,也不再吃生肉
  • 生存的方式也從打獵變成更加細分的職業
  • 到如今的互聯網商業繁榮,大腦思考更加複雜的軟件架構 類比軟件架構:
  • 首先,設計出來的產品可以滿足當前業務需要
  • 之後在實際的應用中迭代,保留優秀設計,剔除無用設計,增加必要設計
  • 最好,當業務發生巨大改變,性能要求更高時,架構要面臨擴展,重構;甚至代碼語言會發生變化,但在演變過程中的經驗,邏輯,設計等會在新的架構中延續。(設計模式強推) 【不要貪大求全,不要盲目照搬大公司的架構】

第三章 架構設計流程

識別複雜度——有針對性

  • 分析業務邏輯的複雜性
  • 是否有做高性能高可用的成本

優先解決最主要的複雜度問題。

使用成熟技術——設計備選方案

  • 備選方案以3-5個為最佳
  • 備選方案差異要比較明顯(比如主備方案和集群方案)
  • 備選方案的技術不要局限已經熟悉的技術(如果你有一把鎚子,那麼所有的問題都是釘子)
  • 備選方案不用過於詳細(關注技術選型,而不是技術細節)

深思熟慮——評估備選方案

  • 性能
  • 複雜度和開發時間
  • 成本
  • 擴展

精雕細琢——詳細方案設計

Nginx負載均衡策略的算法選擇

  • 輪詢
  • 加權輪詢
  • ip_hash