架構設計和常見誤區




一. 什麼是架構和架構本質php


在軟件行業,對於什麼是架構,都有不少的爭論,每一個人都有本身的理解。此君說的架構和彼君理解的架構未必是一回事。所以咱們在討論架構以前,咱們先討論架構的概念定義,概念是人認識這個世界的基礎,並用來溝通的手段,若是對架構概念理解不同,那溝通起來天然不暢。

Linux有架構,MySQL有架構,JVM也有架構,使用Java開發、MySQL存儲、跑在Linux上的業務系統也有架構,應該關注哪個?想要清楚以上問題須要梳理幾個有關係又類似的概念:系統與子系統、模塊與組建、框架與架構。


1.1. 系統與子系統前端


  • 系統:泛指由一羣有關聯的個體組成,根據某種規則運做,能完成個別元件不能獨立完成的工做能力的羣體。nginx

  • 子系統:也是由一羣關聯的個體組成的系統,多半是在更大的系統中的一部分。web


1.2. 模塊與組件數據庫


  • 都是系統的組成部分,從不一樣角度拆分系統而已。模塊是邏輯單元,組件是物理單元。編程

  • 模塊就是從邏輯上將系統分解, 即分而治之, 將複雜問題簡單化。模塊的粒度可大可小, 能夠是系統,幾個子系統、某個服務,函數, 類,方法、 功能塊等等。設計模式

  • 組件能夠包括應用服務、數據庫、網絡、物理機、還能夠包括MQ、容器、Nginx等技術組件。緩存


1.3. 框架與架構tomcat


框架是組件實現的規範,例如:MVC、MVP、MVVM等,是提供基礎功能的產品,例如開源框架:Ruby on Rails、Spring、Laravel、Django等,這是能夠拿來直接使用或者在此基礎上二次開發。

框架是規範,架構是結構。我在這從新定義架構:軟件架構指軟件系統的頂層結構。

架構是通過系統性地思考, 權衡利弊以後在現有資源約束下的最合理決策, 最終明確的系統骨架: 包括子系統, 模塊, 組件. 以及他們之間協做關係, 約束規範, 指導原則.並由它來指導團隊中的每一個人思想層面上的一致。涉及四方面:


  • 系統性思考的合理決策:好比技術選型、解決方案等。
  • 明確的系統骨架:明確系統有哪些部分組成。
  • 系統協做關係:各個組成部分如何協做來實現業務請求。
  • 約束規範和指導原則:保證系統有序,高效、穩定運行。


所以架構師具有能力:理解業務,全局把控,選擇合適技術,解決關鍵問題、指導研發落地實施。架構的本質就是對系統進行有序化地重構以至符合當前業務的發展,並能夠快速擴展。

那什麼樣的系統要考慮作架構設計 技術不會無緣無故的出和自驅動發展起來,而架構的發展和需求是基於業務的驅動。架構設計徹底是爲了業務:
  • 需求相對複雜
  • 非功能性需求在整個系統佔據重要位置.
  • 系統生命週期長,有擴展性需求.
  • 系統基於組件或者集成的須要.
  • 業務流程再造的須要.


二. 架構分層和分類


架構分類可細分爲業務架構、應用架構、技術架構, 代碼架構, 部署架構



業務架構是戰略,應用架構是戰術,技術架構是裝備。其中應用架構承上啓下,一方面承接業務架構的落地,另外一方面影響技術選型。安全


熟悉業務,造成業務架構,根據業務架構,作出相應的應用架構,最後技術架構落地實施。

如何針對當前需求,選擇合適的應用架構,如何面向將來,保證架構平滑過渡,這個是軟件開發者,特別是架構師,都須要深刻思考的問題。


2.1. 業務架構(俯視架構)


包括業務規劃,業務模塊、業務流程,對整個系統的業務進行拆分,對領域模型進行設計,把現實的業務轉化成抽象對象。

沒有最優的架構,只有最合適的架構,一切系統設計原則都要以解決業務問題爲最終目標,脫離實際業務的技術情懷架構每每會給系統帶入大坑,任何不基於業務作異想天開的架構都是耍流氓。

全部問題的前提要搞清楚咱們今天面臨的業務量有多大,增加走勢是什麼樣,並且解決高併發的過程,必定是一個按部就班逐步的過程。合理的架構可以提早預見業務發展1~2年爲宜。這樣能夠付出較爲合理的代價換來真正達到技術引領業務成長的效果。


看看京東業務架構(網上分享圖)


2.2. 應用架構(剖面架構或邏輯架構圖)


硬件到應用的抽象,包括抽象層和編程接口。應用架構和業務架構是相輔相成的關係。業務架構的每一部分都有應用架構。



應用架構:應用做爲獨立可部署的單元,爲系統劃分了明確的邊界,深入影響系統功能組織、代碼開發、部署和運維等各方面. 應用架構定義系統有哪些應用、以及應用之間如何分工和合做。

這裏所謂應用就是各個邏輯模塊或者子系統。 應用架構圖關鍵有2點:


① 職責劃分:明確應用(各個邏輯模塊或者子系統)邊界
  • 邏輯分層;子系統、模塊定義;關鍵類。


②職責之間的協做:
  • 接口協議:應用對外輸出的接口。

  • 協做關係:應用之間的調用關係。




應用分層有兩種方式:

  • 一種是水平分(橫向),按照功能處理順序劃分應用,好比把系統分爲web前端/中間服務/後臺任務,這是面向業務深度的劃分。

  • 另外一種是垂直分(縱向),按照不一樣的業務類型劃分應用,好比進銷存系統能夠劃分爲三個獨立的應用,這是面向業務廣度的劃分。




應用的合反映應用之間如何協做,共同完成複雜的業務case,主要體如今應用之間的通信機制和數據格式,通信機制能夠是同步調用/異步消息/共享DB訪問等,數據格式能夠是文本/XML/JSON/二進制等。


應用的分偏向於業務,反映業務架構,應用的合偏向於技術,影響技術架構。分下降了業務複雜度,系統更有序,合增長了技術複雜度,系統更無序。

應用架構的本質是經過系統拆分,平衡業務和技術複雜性,保證系統形散神不散。

系統採用什麼樣的應用架構,受業務複雜性影響,包括企業發展階段和業務特色;同時受技術複雜性影響,包括IT技術發展階段和內部技術人員水平。業務複雜性(包括業務量大)必然帶來技術複雜性,應用架構目標是解決業務複雜性的同時,避免技術太複雜,確保業務架構落地。


2.3. 數據架構


數據架構指導數據庫的設計,不只僅要考慮開發中涉及到的數據庫,實體模型,也要考慮物理架構中數據存儲的設計。



2.4. 代碼架構(也叫開發架構)


子系統代碼架構主要爲開發人員提供切實可行的指導,若是代碼架構設計不足,就會形成影響全局的架構設計。好比公司內不一樣的開發團隊使用不一樣的技術棧或者組件,結果公司總體架構設計就會失控。


代碼架構主要定義:


① 代碼單元:
  • 配置設計; 框架、類庫。
②代碼單元組織:
  • 編碼規範,編碼的慣例; 項目模塊劃分
  • 頂層文件結構設計,好比mvc設計。
  • 依賴關係


2.5. 技術架構


技術架構:肯定組成應用系統的實際運行組件(lvs,nginx,tomcat,php-fpm等),這些運行組件之間的關係,以及部署到硬件的策略。 技術架構主要考慮系統的非功能性特徵,對系統的高可用、高性能、擴展、安全、伸縮性、簡潔等作系統級的把握。

系統架構的設計要求架構師具有軟件和硬件的功能和性能的過硬知識,這也是架構設計工做中最爲困難的工做。


2.6. 部署拓撲架構圖(實際物理架構圖)


拓撲架構,包括架構部署了幾個節點,節點之間的關係,服務器的高可用,網路接口和協議等,決定了應用如何運行,運行的性能,可維護性,可擴展性,是全部架構的基礎。這個圖主要是運維工程師主要關注的對象。



物理架構主要考慮硬件選擇和拓撲結構,軟件到硬件的映射,軟硬件的相互影響。



三. 架構級別


咱們使用金字塔的架構級別來講明,上層級別包含下層:


  • 系統級:即整個系統內各部分的關係以及如何治理:分層
  • 應用級:即單個應用的總體架構,及其與系統內單個應用的關係等。
  • 模塊級:即應用內部的模塊架構,如代碼的模塊化、數據和狀態的管理等。
  • 代碼級:即從代碼級別保障架構實施。

戰略設計與戰術設計:基於架構金字塔,咱們有了系統架構的戰略設計與戰術設計的完美結合:

  • 戰略設計:業務架構用於指導架構師如何進行系統架構設計。
  • 戰術設計:應用架構要根據業務架構來設計。
  • 戰術實施:應用架構肯定之後,就是技術選型。


四. 應用架構演進


業務架構是生產力,應用架構是生產關係,技術架構是生產工具。業務架構決定應用架構,應用架構須要適配業務架構,並隨着業務架構不斷進化,同時應用架構依託技術架構最終落地。



架構演進路程:單體應用->分佈式應用服務化->微服務。


4.1. 單體應用


企業一開始業務比較簡單,只應用某個簡單場景,應用服務支持數據增刪改查和簡單的邏輯便可,單體應用能夠知足要求。

典型的三級架構,前端(Web/手機端)+中間業務邏輯層+數據庫層。這是一種典型的Java Spring MVC或者Python Django框架的應用。其架構圖以下所示:

針對單體應用,非功能性需求的作法:


  • 性能需求:使用緩存改善性能
  • 併發需求:使用集羣改善併發
  • 讀寫分離:數據庫地讀寫分離
  • 使用反向代理和cdn加速;使用分佈式文件和分佈式數據庫


單體架構的應用比較容易部署、測試, 在項目的初期,單體應用能夠很好地運行。然而,隨着需求的不斷增長, 愈來愈多的人加入開發團隊,代碼庫也在飛速地膨脹。慢慢地,單體應用變得愈來愈臃腫,可維護性、靈活性逐漸下降,維護成本愈來愈高。下面是單體架構應用的一些缺點:


  • 複雜性高:以一個百萬行級別的單體應用爲例,整個項目包含的模塊很是多、模塊的邊界模糊、 依賴關係不清晰、 代碼質量良莠不齊、 混亂地堆砌在一塊兒。可想而知整個項目很是複雜。每次修改代碼都心驚膽戰, 甚至添加一個簡單的功能, 或者修改一個Bug都會帶來隱含的缺陷。

  • 技術債務:隨着時間推移、需求變動和人員更迭,會逐漸造成應用程序的技術債務, 而且越積 越多。「 不壞不修」, 這在軟件開發中很是常見, 在單體應用中這種思想更甚。已使用的系統設計或代碼難以被修改,由於應用程序中的其餘模塊可能會以意料以外的方式使用它。

  • 部署頻率低:隨着代碼的增多,構建和部署的時間也會增長。而在單體應用中, 每次功能的變動或缺陷的修復都會致使須要從新部署整個應用。全量部署的方式耗時長、 影響範圍大、 風險高, 這使得單體應用項目上線部署的頻率較低。而部署頻率低又致使兩次發佈之間會有大量的功能變動和缺陷修復,出錯率比較高。

  • 可靠性差:某個應用Bug,例如死循環、內存溢出等, 可能會致使整個應用的崩潰。

  • 擴展能力受限:單體應用只能做爲一個總體進行擴展,沒法根據業務模塊的須要進行伸縮。例如,應用中有的模塊是計算密集型的,它須要強勁的CPU;有的模塊則是IO密集型的,須要更大的內存。因爲這些模塊部署在一塊兒,不得不在硬件的選擇上作出妥協。

  • 阻礙技術創新:單體應用每每使用統一的技術平臺或方案解決全部的問題, 團隊中的每一個成員 都必須使用相同的開發語言和框架,要想引入新框架或新技術平臺會很是困難。


4.2. 分佈式

隨着業務深刻,業務要求的產品功能愈來愈多,每一個業務模塊邏輯也都變得更加複雜,業務的深度和廣度都增長,使得單體應用變得愈來愈臃腫,可維護性、靈活性逐漸下降,增長新功能開發週期愈來愈長,維護成本愈來愈高。


這時須要對系統按照業務功能模塊拆分,將各個模塊服務化,變成一個分佈式系統。業務模塊分別部署在不一樣的服務器上,各個業務模塊之間經過接口進行數據交互。


該架構相對於單體架構來講,這種架構提供了負載均衡的能力,大大提升了系統負載能力,解決了網站高併發的需求。另外還有如下特色:


  • 下降了耦合度:把模塊拆分,使用接口通訊,下降模塊之間的耦合度。

  • 責任清晰:把項目拆分紅若干個子項目,不一樣的團隊負責不一樣的子項目。

  • 擴展方便:增長功能時只須要再增長一個子項目,調用其餘系統的接口就能夠。

  • 部署方便:能夠靈活的進行分佈式部署。

  • 提升代碼的複用性:好比Service層,若是不採用分佈式rest服務方式架構就會在手機Wap商城,微信商城,PC,Android,iOS每一個端都要寫一個Service層邏輯,開發量大,難以維護一塊兒升級,這時候就能夠採用分佈式rest服務方式,公用一個service層。

  • 缺點:系統之間的交互要使用遠程通訊,接口開發增大工做量,可是利大於弊。


4.3. 微服務

緊接着業務模式愈來愈複雜,訂單、商品、庫存、價格等各個模塊都很深刻,好比價格區分會員等級,訪問渠道(app仍是PC),銷售方式(團購仍是普通)等,還有大量的價格促銷,這些規則很複雜,容易相互衝突,須要把分散到各個業務的價格邏輯進行統一管理,以基礎價格服務的方式透明地提供給上層應用,變成一個微內核的服務化架構,即微服務。


微服務的特色:


  • 易於開發和維護:一個微服務只會關注一個特定的業務功能,因此它業務清晰、代碼量較少。開發和維護單個微服務相對簡單。而整個應用是由若干個微服務構建而成的,因此整個應用也會被維持在一個可控狀態。

  • 單個微服務啓動較快:單個微服務代碼量較少, 因此啓動會比較快。

  • 局部修改容易部署:單體應用只要有修改,就得從新部署整個應用,微服務解決了這樣的問題。通常來講,對某個微服務進行修改,只須要從新部署這個服務便可。

  • 技術棧不受限:在微服務架構中,能夠結合項目業務及團隊的特色,合理地選擇技術棧。例如某些服務可以使用關係型數據庫MySQL;某些微服務有圖形計算的需求,可使用Neo4j;甚至可根據須要,部分微服務使用Java開發,部分微服務使用Node.js開發。


微服務雖然有不少吸引人的地方,但它並非免費的午飯,使用它是有代價的。使用微服務架構面臨的挑戰。


  • 運維要求較高:更多的服務意味着更多的運維投入。在單體架構中,只須要保證一個應用的正常運行。而在微服務中,須要保證幾十甚至幾百個服務服務的正常運行與協做,這給運維帶來了很大的挑戰。

  • 分佈式固有的複雜性:使用微服務構建的是分佈式系統。對於一個分佈式系統,系統容錯、網絡延遲、分佈式事務等都會帶來巨大的挑戰。

  • 接口調整成本高:微服務之間經過接口進行通訊。若是修改某一個微服務的API,可能全部使用了該接口的微服務都須要作調整。

  • 重複勞動:不少服務可能都會使用到相同的功能,而這個功能並無達到分解爲一個微服務的程度,這個時候,可能各個服務都會開發這一功能,從而致使代碼重複。儘管可使用共享庫來解決這個問題(例如能夠將這個功能封裝成公共組件,須要該功能的微服務引用該組件),但共享庫在多語言環境下就不必定行得通了。


五. 衡量架構的合理性


架構爲業務服務,沒有最優的架構,只有最合適的架構,架構始終以高效,穩定,安全爲目標來衡量其合理性。合理的架構設計:


5.1. 業務需求角度

  • 能解決當下業務需求和問題

  • 高效完成業務需求: 能以優雅且可複用的方式解決當下全部業務問題

  • 前瞻性設計: 能在將來一段時間都能以第2種方式知足業務,從而不會每次當業務進行演變時,致使架構翻天覆地的變化。


5.2. 非業務需求角度


①穩定性指標:
  • 高可用:要儘量的提升軟件的可用性,我想每一個操做人都不肯意看到本身的工做沒法正常進行。黑盒白盒測試、單元測試、自動化測試、故障注入測試、提升測試覆蓋率等方式來一步一步推動。


②高效指標:

  • 文檔化:無論是總體仍是部分的整個生命週期內都必須作好文檔化,變更的來源包括但不限於BUG,需求。
  • 可擴展:軟件的設計秉承着低耦合的理念去作,注意在合理的地方抽象。方便功能更改、新增和運用技術的迭代,而且支持在適時對架構作出重構。
  • 高複用:爲了不重複勞動,爲了下降成本,咱們但願可以重用以前的代碼、以前的設計。這點對於架構環境的依賴是最大的。

③安全指標
  • 安全:組織的運做過程當中產生的數據都是具備商業價值的,保證數據的安全也是刻不容緩的一部分。以避免出現XX門之類醜聞。加密、https等爲廣泛手段


六. 常見架構誤區


  • 遺漏關鍵性約束與非功能需求
  • 爲虛無的將來埋單而過分設計
  • 過早作出關鍵性決策
  • 客戶說啥就是啥成爲傳話筒
  • 埋頭幹活兒缺少前瞻性
  • 架構設計還要考慮系統可測性
  • 架構設計不要企圖一步到位



常見誤區


  • 誤區1——架構專門由架構師來作,業務開發人員無需關注:架構的再好,最終仍是須要代碼來落地,而且組織越大這個落地的難度越大。不僅僅是系統架構,每一個解決方案每一個項目也由本身的架構,如分層、設計模式等。若是每一塊磚瓦不夠堅固,那麼整個系統仍是會由崩塌的風險。所謂「千里之堤,潰於蟻穴」。


  • 誤區2——架構師肯定了架構藍圖以後任務就結束了:架構不是「空中樓閣」,最終仍是要落地的,可是架構師徹底不去深刻到第一線怎麼知道「地」在哪?怎麼才能落的穩妥當當。


  • 誤區3——不作出完美的架構設計不開工:世上沒有最好架構,只有最合適的架構,不要企圖一步到位。咱們須要的不是一會兒造出一輛汽車,而是從單輪車→自行車→摩托車,最後再到汽車。想象一下2年後才能造出的產品,當初市場還存在嗎?


  • 誤區4—— 爲虛無的將來埋單而過分設計:在創業公司初期,業務場景和需求邊界很難把握,產品須要快速迭代和變現,需求頻繁更新,這個時候須要的是快速實現。不要過多考慮將來的擴展,說不定功能作完,效果很差就無用了。若是業務模式和應用場景邊界都已經比較清晰,是應該適當的考慮將來的擴展性設計。


  • 誤區5——一味追隨大公司的解決方案:因爲大公司巨大成功的光環效應,再加上從大公司挖來的技術高手的影響,網站在討論架構決策時,最有說服力的一句話就成了「淘寶就是這麼搞的」或者「騰訊 就是這麼搞的」。大公司的經驗和成功模式當然重要,值得學習借鑑,但若是所以而變得盲從,就失去了堅持自個人勇氣,在架構演化的道路上早晚會迷路。


  • 誤區6——爲了技術而技術:技術是爲業務而存在的,除此毫無心義。在技術選型和架構設計中,脫離網站業務發展的實際,一味追求時髦的新技術,可能會將技術發展引入崎嶇小道,架構之路越走越難。考慮實現成本、時間、人員等各方面都要綜合考慮,理想與現實須要折中。


原文連接:

https://blog.csdn.net/hguisu/article/details/78258430


推薦閱讀:

如何成爲一個騷氣的架構師,看這一篇就夠了

億級(無限級)併發,沒那麼難

怎麼樣的架構圖算優秀?看看這個你就懂了!

阿里巴巴的技術專家,是如何畫好架構圖的?

架構設計實踐思路:什麼是架構,怎麼畫架構圖?



本文分享自微信公衆號 - 肉眼品世界(find_world_fine)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索