架構設計的問題與解法
把書讀薄之『從0開始學架構』
0、引語
小到某個功能的開發(fā)方案,大到整個業(yè)務的系統設計,都可以看到架構設計的影子,但是架構設計的目的到底是什么?『從0開始學架構』的作者給我們的解答是:架構設計的主要目的是為了解決軟件系統復雜度帶來的問題。
這里其實有兩個重點:一是問題,二是解決。
(相關資料圖)
首先得知道我們要解決的問題在哪里?面前的系統到底有什么復雜度導致的問題?只有知道了問題才能選擇解法,不能拿著錘子找釘子。
當知道了當前面臨的問題后,就要利用前人的智慧和自身的經驗,設計出合理的架構方案來解決問題。
因此對整本書的內容,分成以下四節(jié),第一節(jié)主要描述我們通常面臨的系統復雜度及問題在哪,后面三節(jié)則是對常見的三個問題下的常用解法進行闡述。
1、基本概念與設計方法
在講解架構思想之前,先統一介紹一下基本概念的含義,避免每個人對系統、框架、架構這些名詞的理解不一致導致的誤解。下面是作者對每個名詞的定義,其作用域僅限本文范疇,不用糾結其在其他上下文中的意義。
系統:系統泛指由一群有關聯的個體組成,根據某種規(guī)則運作,能完成個別元件不能單獨完成的工作的群體。子系統:子系統也是由一群有關聯的個體所組成的系統,多半會是更大系統中的一部分。模塊:從業(yè)務邏輯的角度來拆分系統后,得到的單元就是“模塊”。劃分模塊的主要目的是職責分離。組件:從物理部署的角度來拆分系統后,得到的單元就是“組件”。劃分組件的主要目的是單元復用??蚣埽菏且徽组_發(fā)規(guī)范,是提供基礎功能的產品。架構:關注的是結構,是某一套開發(fā)規(guī)范下的具體落地方案,包括各個模塊之間的組合關系以及它們協同起來完成功能的運作規(guī)則。由以上定義可見,所謂架構,是為了解決軟件系統的某個復雜度帶來的具體問題,將模塊和組件以某種方式有機組合,基于某個具體的框架實現后的一種落地方案。
而討論架構時,往往只討論到系統與子系統這個頂層的架構。
可見,要進行架構選型,首先應該知道自己要解決的業(yè)務和系統復雜點在哪里,是作為秒殺系統有瞬間高并發(fā),還是作為金融科技有極高的數據一致性和可用性要求等。
一般來說,系統的復雜度來源有以下幾個方面:
高性能:
如果業(yè)務的訪問頻率或實時性要求較高,則會對系統提出高性能的要求。
如果是單機系統,需要利用多進程、多線程技術。
如果是集群系統,則還涉及任務拆分、分配與調度,多機器狀態(tài)管理,機器間通信,當單機性能達到瓶頸后,即使繼續(xù)加機器也無法繼續(xù)提升性能,還是要針對單個子任務進行性能提升。
高可用:
如果業(yè)務的可用性要求較高,也會帶來高可用方面的復雜度。高可用又分為計算高可用和存儲高可用。
針對計算高可用,可以采用主備(冷備、溫備、熱備)、多主的方式來冗余計算能力,但會增加成本、可維護性方面的復雜度。
針對存儲高可用,同樣是增加機器來冗余,但這也會帶來多機器導致的數據不一致問題,如遇到延遲、中斷、故障等情況。難點在于怎么減少數據不一致對業(yè)務的影響。
既然主要解決思路是增加機器來做冗余,那么就涉及到了狀態(tài)決策的問題。即如果判斷當前主機的狀態(tài)是正常還是異常,以及異常了要如何采取行動(比如切換哪臺做主機)。
對主機狀態(tài)的判斷,多采用機器信息采集或請求響應情況分析等手段,但又會產生采集信息這一條通信鏈路本身是否正常的問題,下文會具體展開討論。事實上,狀態(tài)決策本質上不可能做到完全正確。
而對于決策方式,有以下幾種方式:
獨裁式:存在一個獨立的決策主體來收集信息并決定主機,這樣的策略不會混亂,但這個主體本身存在單點問題。協商式:兩臺備機通過事先指定的規(guī)則來協商決策出主機,規(guī)則雖然簡單方便,但是如果兩臺備機之間的協商鏈路中斷了,決策起來就會很困難,比如有網絡延遲且機器未故障、網絡中斷且機器未故障、網絡中斷其機器已故障,多種情況需要處理。民主式:如果有多臺備機,可以使用選舉算法來投票出主機,比如Paxos就是一種選舉算法,這種算法大多數都采取多數取勝的策略,算法本身較為復雜,且如果像協商式一樣出現連接中斷,就會腦裂,不同部分會各自決策出不同結果,需要規(guī)避。可擴展性:
眾所周知在互聯網行業(yè)只有變化才是永遠不變的,而開發(fā)一個系統基本都不是一蹴而就的,那應該如何為系統的未來可能性進行設計來保持可擴展性呢?
這里首先要明確的一個觀點就是,在做系統設計時,既不可能完全不考慮可擴展性,也不可能每個設計點都考慮可擴展性,前者很明顯,后者則是為了避免舍本逐末,為了擴展而擴展,實際上可能會為不存在的預測花費過多的精力。
那么怎么考慮系統的未來可能性從而做出相應的可擴展性設計呢?這里作者給出了一個方法:只預測兩年內可能的變化,不要試圖預測五年乃至十年的變化。因為對于變化快的行業(yè)來說,預測兩年已經足夠遠了,再多就可能計劃趕不上變化。而對變化慢的行業(yè),則預測的意義更是不大。
要應對變化,主要是將變與不變分隔開來。
這里可以針對業(yè)務,提煉變化層和穩(wěn)定層,通過變化層將變化隔離。比如通過一個DAO服務來對接各種變化的存儲載體,但是上層穩(wěn)定的邏輯不用知曉當前采用何種存儲,只需按照固定的接口訪問DAO即可獲取數據。
也可以將一些實現細節(jié)剝離開來,提煉出抽象層,僅在實現層去封裝變化。比如面對運營上經常變化的業(yè)務規(guī)則,可以提煉出一個規(guī)則引擎來實現核心的抽象邏輯,而具體的規(guī)則實現則可以按需增加。
如果是面對一個舊系統的維護,接到了新的重復性需求,而舊系統并不支持較好的可擴展性,這時是否需要花費時間精力去重構呢?作者也提出了《重構》一書中提到的原則:事不過三,三則重構。
簡而言之,不要一開始就考慮復雜的做法去滿足可擴展性,而是等到第三次遇到類似的實現時再來重構,重構的時候采取上述說的隔離或者封裝的方案。這一原則對
這一原則對新系統開發(fā)也是適用的。總而言之就是,不要為難以預測的未來去過度設計,為明確的未來保留適量的可擴展性即可。
低成本:
上面說的高性能、高可用都需要增加機器,帶來的是成本的增加,而很多時候研發(fā)的預算是有限的。換句話說,低成本往往并不是架構設計的首要目標,而是設計架構時的約束限制。
那如何在有限的成本下滿足復雜性要求呢?往往只有“創(chuàng)新”才能達到低成本的目標。舉幾個例子:
NoSQL的出現是為解決關系型數據庫應對高并發(fā)的問題。全文搜索引擎的出現是為解決數據庫like搜索效率的問題。Hadoop的出現是為解決文件系統無法應對海量數據存儲與計算的問題。Facebook的HipHop PHP和HHVM的出現是為解決PHP運行低效問題。新浪微博引入SSD Cache做L2緩存是為解決Redis高成本、容量小、穿透DB的問題。Linkedin引入Kafka是為解決海量事件問題。上述案例都是為了在不顯著增加成本的前提下,實現系統的目標。
這里還要說明的是,創(chuàng)造新技術的復雜度本身就是很高的,因此一般中小公司基本都是靠引入現有的成熟新技術來達到低成本的目標;而大公司才更有可能自己去創(chuàng)造新的技術來達到低成本的目標,因為大公司才有足夠的資源、技術和時間去創(chuàng)造新技術。
安全:
安全是一個研發(fā)人員很熟悉的目標,從整體來說,安全包含兩方面:功能安全和架構安全。
功能安全是為了“防小偷”,即避免系統因安全漏洞而被竊取數據,如SQL注入。常見的安全漏洞已經有很多框架支持,所以更建議利用現有框架的安全能力,來避免重復開發(fā),也避免因自身考慮不夠全面而遺漏。在此基礎上,仍需持續(xù)攻防來完善自身的安全。
架構安全是為了“防強盜“,即避免系統被暴力攻擊導致系統故障,比如DDOS攻擊。這里一方面只能通過防火墻集運營商或云服務商的大帶寬和流量清洗的能力進行防范,另一方面也需要做好攻擊發(fā)現與干預、恢復的能力。
規(guī)模:
架構師在宣講時往往會先說自己任職和設計過的大型公司的架構,這是因為當系統的規(guī)模達到一定程度后,復雜度會發(fā)生質的變化,即所謂量變引起質變。
這個量,體現在訪問量、功能數量及數據量上。
訪問量映射到對高性能的要求。功能數量需要視具體業(yè)務會帶來不同的復雜度。而數據量帶來的收集、加工、存儲、分析方面的挑戰(zhàn),現有的方案基本都是給予Google的三篇大數據論文的理論:
Google File System 是大數據文件存儲的技術理論Google Bigtable 是列式數據存儲的技術理論Google MapReduce 是大數據運算的技術理論經過上面的分析可以看到,復雜度來源很多,想要一一應對,似乎會得到一個復雜無比的架構,但對于架構設計來說,其實剛開始設計時越簡單越好,只要能解決問題,就可以從簡單開始再慢慢去演化,對應的是下面三條原則:
合適原則:不需要一開始就挑選業(yè)界領先的架構,它也許優(yōu)秀,但可能不那么適合自己,比如有很多目前用不到的能力或者大大超出訴求從而增加很多成本。其實更需要考慮的是合理地將資源整合在一起發(fā)揮出最大功效,并能夠快速落地。簡單原則:有時候為了顯示出自身的能力,往往會在一開始就將系統設計得非常復雜,復雜可能代表著先進,但更可能代表著“問題”,組件越多,就越可能出故障,越可能影響關聯著的組件,定位問題也更加困難。其實只要能夠解決訴求即可。演化原則:不要妄想一步到位,沒有人可以準確預測未來所有發(fā)展,軟件不像建筑,變化才是主題。架構的設計應該先滿足業(yè)務需求,適當的預留擴展性,然后在未來的業(yè)務發(fā)展中再不斷地迭代,保留有限的設計,修復缺陷,改正錯誤,去除無用部分。這也是重構、重寫的價值所在。即使是QQ、淘寶這種如今已經非常復雜的系統,剛開始時也只是一個簡單的系統,甚至淘寶都是直接買來的系統,隨著業(yè)務發(fā)展也只是先加服務器、引入一些組件解決性能問題,直到達到瓶頸才去重構重寫,重新在新的復雜度要求下設計新的架構。
明確了設計原則后,當面對一個具體的業(yè)務,可以按照如下步驟進行架構設計:
識別復雜度:無論是新設計一個系統還是接手一個混亂的系統,第一步都是先將主要的復雜度問題列出來,然后根據業(yè)務、技術、團隊等綜合情況進行排序,優(yōu)先解決當前面臨的最主要的復雜度問題。復雜度的主要來源上文已經說過,可以按照經驗或者排查法進行分析。方案對比:先看看業(yè)界是否有類似的業(yè)務,了解他們是怎么解決問題的,然后提出3~5個備選方案,不要只考慮做一個最優(yōu)秀的方案,一個人的認知范圍常常是有限的,逼自己多思考幾個方案可以有效規(guī)避因為思維狹隘導致的局限性,當然也不要過多,不用給出非常詳細的方案,太消耗精力。備選方案的差異要比較明顯,才有擴寬思路和對比的價值。設計詳細方案:當多個方案對比得出最終選擇后,就可以對目標方案進行詳細的設計,關鍵細節(jié)需要比較深入,如果方案本身很復雜,也可以采取分步驟、分階段、分系統的實現方式來降低實現復雜度。當方案非常龐大的時候,可以匯集一個團隊的智慧和經驗來共同設計,防止因架構師的思維盲區(qū)導致問題。2、高性能架構模式
2.1、存儲高性能
互聯網業(yè)務大多是數據密集型的業(yè)務,其對性能的壓力也常常來自于海量用戶對數據的高頻讀寫壓力上,因此解決高性能問題,首先要解決數據讀寫的存儲高性能問題。
讀寫分離:
在大多數業(yè)務中,用戶查詢和修改數據的頻率是不同的,甚至是差別很大的,大部分情況下都是讀多寫少的,因此可以將對數據的讀和寫操作分開對待,對壓力更大的讀操作提供額外的機器分擔壓力,這就是讀寫分離。
讀寫分離的基本實現是搭建數據庫的主從集群,根據需要提供一主一從或一主多從。
注意是主從不是主備,從和備的差別在于從機是要干活的。
通常在讀多寫少的情況下,主機負責讀寫操作,從機只負責讀操作,負責幫主機分擔讀操作的壓力。而數據會通過復制機制(如全同步、半同步、異步)同步到從機,每臺服務器都有所有業(yè)務數據。
既然有數據的同步,就一定存在復制延遲導致的從機數據不一致問題,針對這個問題有幾種常見的解法,如:
寫操作后同一用戶一段時間內的讀操作都發(fā)給主機,避免數據還沒同步到從機,但這個邏輯容易遺漏。讀從機失敗后再讀一次主機,該方法只能解決新數據未同步的問題,無法解決舊數據修改的問題(不會讀取失?。叶巫x取主機會給主機帶來負擔,容易被針對性攻擊。關鍵讀寫操作全部走主機,從機僅負責非關鍵鏈路的讀,該方法是基于保障關鍵業(yè)務的思路。除了數據同步的問題之外,只要涉及主從機同時支持業(yè)務訪問的,就一定需要制定請求分配的機制。上面說的幾個問題解法也涉及了一些分配機制的細節(jié)。具體到分配機制的實現來說,有兩種思路:
程序代碼封裝:實現簡單,可對業(yè)務定制化,但每個語言都要自己實現一次,且很難做到同步修改,因此適合小團隊。中間件封裝:獨立出一套系統管理讀寫的分配,對業(yè)務透明,兼容SQL協議,業(yè)務服務器就無需做額外修改適配。需要支持多語言、完整的SQL語法,涉及很多細節(jié),容易出BUG,且本身是個單點,需要特別保障性能和可用性,因此適合大公司。分庫分表:
除了高頻訪問的壓力,當數據量大了以后,也會帶來數據庫存儲方面的壓力。此時就需要考慮分庫分表的問題。分庫分表既可以緩解訪問的壓力,也可以分散存儲的壓力。
先說分庫,所謂分庫,就是指業(yè)務按照功能、模塊、領域等不同,將數據分散存儲到不同的數據庫實例中。
比如原本是一個MySQL數據庫實例,在庫中按照不同業(yè)務建了多張表,大體可以歸類為A、B兩個領域的數據?,F在新建一個庫,將原庫中A領域的數據遷移到新的庫中存儲,還是按需建表,而B領域的數據繼續(xù)留在原庫中。
分庫一方面可以緩解訪問和存儲的壓力,另一方面也可以增加抗風險能力,當一個庫出問題后,另一個庫中的數據并不會受到影響,而且還能分開管理權限。
但分庫也會帶來一些問題,原本同一個庫中的不同表可以方便地進行聯表查詢,分庫后則會變得很復雜。由于數據在不同的庫中,當要操作兩個庫中的數據時,無法使用事務操作,一致性也變得更難以保障。而且當增加備庫來保障可用性的時候,成本是成倍增加的。
基于以上問題,初創(chuàng)的業(yè)務并不建議在一開始就做這種拆分,會增加很多開發(fā)時的成本和復雜度,拖慢業(yè)務的節(jié)奏。
再說分表,所謂分表,就是將原本存儲在一張表里的數據,按照不同的維度,拆分成多張表來存儲。
按照訴求與業(yè)務的特性不同,可以采用垂直分表或水平分表的方式。
垂直分表相當于垂直地給原表切了一刀,把不同的字段拆分到不同的子表中,這樣拆分后,原本訪問一張表可以獲取的所有字段,現在則需要訪問不同的表獲取。
垂直分表適合將表中某些不常用又占了大量空間的列(字段)拆分出去,可以提升訪問常用字段的性能。
但相應的,當真的需要的字段處于不同表中時,或者要新增記錄存儲所有字段數據時,要操作的表變多了。
水平分表相當于橫著給原表切了一刀,那么原表中的記錄會被分散存儲到不同的子表中,但是每張子表的字段都是全部字段。
水平分表適合表的量級很大以至影響訪問性能的場景,何時該拆分并沒有絕對的指標,一般記錄數超過千萬時就需要警覺了。
不同于垂直分表依然能訪問到所有記錄,水平分表后無法再在一張表中訪問所有數據了,因此很多查詢操作會受到影響,比如join操作就需要多次查詢后合并結果,count操作也需要計算多表的結果后相加,如果經常用到count的總數,可以額外維護一個總數表去更新,但也會帶來數據一致性的問題。
值得特別提出的是范圍查詢,原本的一張表可以通過范圍查詢到的數據,分表后也需要多次查詢后合并數據,如果是業(yè)務經常用到的范圍查詢,那建議干脆就按照這種方式來分表,這也是分表的路由方式之一:范圍路由。
所謂路由方式是指:分表后當新插入記錄時,如何判斷該往哪張表插入。常用的插入方式有以下三種:
范圍路由:按照時間范圍、ID范圍或者其他業(yè)務常用范圍字段路由。這種方式在擴充新的表時比較方便,直接加表給新范圍的數據插入即可,但是數量和冷熱分布可能是不均勻的。Hash路由:根據Hash運算來路由新記錄插入的表,這種方式需要提前就規(guī)劃好分多少張表,才能決定Hash運算方式,但表數量其實很難預估,導致未來需要擴充新表時很麻煩,但數據在不同表中的分布是比較均勻的。配置路由:新增一個路由表來記錄數據id和表id的映射,按照自定義的方式隨時修改映射規(guī)則,設計簡單,擴充新表也很方便,但每次操作表都需要額外操作一次路由表,其本身也成為了單點瓶頸。無論是垂直分表還是水平分表,單表切分為多表后,新的表即使在同一個數據庫服務器中,也可能帶來可觀的性能提升,如果性能能夠滿足業(yè)務要求,可以不拆分到多臺數據庫服務器,畢竟分庫也會引入很多復雜性的問題;如果單表拆分為多表后,單臺服務器依然無法滿足性能要求,那就不得不再次進行業(yè)務分庫的設計了。
NoSQL數據庫:
上面發(fā)分庫分表討論的都是關系型數據庫的優(yōu)化方案,但關系型數據庫也有其無法規(guī)避的缺點,比如無法直接存儲某種結構化的數據、擴展表結構時會鎖表影響線上性能、大數據場景下I/O較高、全文搜索的功能比較弱等。
基于這些缺點,也有很多新的數據庫框架被創(chuàng)造出來,解決其某方面的問題。
比如以Redis為代表的的KV存儲,可以解決無法存儲結構化數據的問題;以MongoDB為代表的的文檔數據庫可以解決擴展表結構被強Schema約束的問題;以HBase為代表的的列式數據庫可以解決大數據場景下的I/O問題;以ES為代表的的全文搜索引擎可以解決全文檢索效率的問題等。
這些數據庫統稱為NoSQL數據庫,但NoSQL并不是全都不能寫SQL,而是Not Only SQL的意思。
NoSQL數據庫除了聚焦于解決某方面的問題以外也會有其自身的缺點,比如Redis沒有支持完整的ACID事務、列式存儲在更新一條記錄的多字段時性能較差等。因此并不是說使用了NoSQL就能一勞永逸,更多的是按需取用,解決業(yè)務面臨的問題。
關于NoSQL的更多了解,也可以看看《NoSQL精粹》這本書。
緩存:
如果NoSQL也解決不了業(yè)務的高性能訴求,那么或許你需要加點緩存。
緩存最直接的概念就是把常用的數據存在內存中,當業(yè)務請求來查詢的時候直接從內存中拿出來,不用重新去數據庫中按條件查詢,也就省去了大量的磁盤IO時間。
一般來說緩存都是通過Key-Value的方式存儲在內存中,根據存儲的位置,分為單機緩存和集中式緩存。單機緩存就是存在自身服務器所在的機器上,那么勢必會有不同機器數據可能不一致,或者重復緩存的問題,要解決可以使用查詢內容做路由來保障同一記錄始終到同一臺機器上查詢緩存。集中式緩存則是所有服務器都去一個地方查緩存,會增加一些調用時間。
緩存可以提升性能是很好理解的,但緩存同樣有著他的問題需要應對或規(guī)避。數據時效性是最容易想到的問題,但也可以靠同時更新緩存的策略來保障數據的時效性,除此之外還有其他幾個常見的問題。
如果某條數據不存在,緩存中勢必查不到對應的KEY,從而就會請求數據庫確認是否有新增加這條數據,如果始終沒有這條數據,而客戶端又反復頻繁地查詢這條數據,就會變相地對數據庫造成很大的壓力,換句話說,緩存失去了保護作用,請求穿透到了數據庫,這稱為緩存穿透。
應對緩存穿透,最好的手段就是把“空值”這一情況也緩存下來,當客戶端下次再查詢時,發(fā)現緩存中說明了該數據是空值,則不會再問詢數據庫。但也要注意如果真的有對應數據寫入了數據庫,應當能及時清除”空值“緩存。
為了保障緩存的數據及時更新,常常都會根據業(yè)務特性設置一個緩存過期時間,在緩存過期后,到再次生成期間,如果出現大量的查詢,會導致請求都傳遞到數據庫,而且會多次重復生成緩存,甚至可能拖垮整個系統,這就叫緩存雪崩,和緩存穿透的區(qū)別在于,穿透是面對空值的情況,而雪崩是由于緩存重新生成的間隔期大量請求產生的連鎖效應。
既然是緩存更新時重復生成所導致的問題,那么一種解法就是在緩存重新生成前給這個KEY加鎖,加鎖期間出現的請求都等待或返回默認值,而不去都嘗試重新生成緩存。
另一種方法是干脆不要由客戶端請求來觸發(fā)緩存更新,而是由后臺腳本統一更新,同樣可以規(guī)避重復請求導致的重復生成。但是這就失去了只緩存熱點數據的能力,如果緩存因空間問題被清除了,也會因為后臺沒及時更新導致查不到緩存數據,這就會要求更復雜的后臺更新策略,比如主動查詢緩存有效性、緩存被刪后通知后臺主動更新等。
雖說在有限的內存空間內最好緩存熱點數據,但如果數據過熱,比如微博的超級熱搜,也會導致緩存服務器壓力過大而崩潰,稱之為緩存熱點問題。
可以復制多份緩存副本,來分散緩存服務器的單機壓力,畢竟堆機器是最簡單有效。此處也要注意,多個緩存副本不要設置相同的緩存過期時間,否則多處緩存同時過期,并同時更新,也容易引起緩存雪崩,應該設置一個時間范圍內的隨機值來更新緩存。
2.2、計算高性能
講完存儲高性能,再講計算高性能,計算性能的優(yōu)化可以先從單機性能優(yōu)化開始,多進程、多線程、IO多路復用、異步IO等都存在很多可以優(yōu)化的地方,但基本系統或框架已經提供了基本的優(yōu)化能力,只需使用即可。
負載均衡:
如果單機的性能優(yōu)化已經到了瓶頸,無法應對業(yè)務的增長,就會開始增加服務器,構建集群。對于計算來說,每一臺服務器接到同樣的輸入,都應該返回同樣的輸出,當服務器從單臺變成多臺之后,就會面臨請求來了要由哪一臺服務器處理的問題,我們當然希望由當前比較空閑的服務器去處理新的請求,這里對請求任務的處理分配問題,就叫負載均衡。
負載均衡的策略,從分類上來說,可以分為三類:
DNS負載均衡:通過DNS解析,來實現地理級別的均衡,其成本低,分配策略很簡單,可以就近訪問來提升訪問速度,但DNS的緩存時間長,由于更新不及時所以無法快速調整,且控制權在各域名商下,且無法根據后端服務器的狀態(tài)來決定分配策略。硬件負載均衡:直接通過硬件設備來實現負載均衡,類似路由器路由,功能和性能都很強大,可以做到百萬并發(fā),也很穩(wěn)定,支持安全防護能力,但是同樣無法根據后端服務器狀態(tài)進行策略調整,且價格昂貴。軟件負載均衡:通過軟件邏輯實現,比如nginx,比較靈活,成本低,但是性能一般,功能也不如硬件強大。一般來說,DNS 負載均衡用于實現地理級別的負載均衡;硬件負載均衡用于實現集群級別的負載均衡;軟件負載均衡用于實現機器級別的負載均衡。
所以部署起來可以按照這三層去部署,第一層通過DNS將請求分發(fā)到北京、上海、深圳的機房;第二層通過硬件負載均衡將請求分發(fā)到當地三個集群中的一個;第三層通過軟件策略將請求分發(fā)到具體的某臺服務器去響應業(yè)務。
就負載均衡算法來說,多是我們很熟悉的算法,如輪詢、加權輪詢、負載最低優(yōu)先、性能最優(yōu)優(yōu)先、Hash分配等,各有特點,按需采用即可。
3、高可用架構模式
3.1、理論方法
CAP與BASE:
在說高可用之前,先來說說CAP理論,即:
在一個分布式系統(指互相連接并共享數據的節(jié)點的集合)中,當涉及讀寫操作時,只能保證一致性(Consistence)、可用性(Availability)、分區(qū)容錯性(Partition Tolerance)三者中的兩個,另外一個必須被犧牲。
大家可能都知道CAP定理是什么,但大家可能不知道,CAP定理的作者(Seth Gilbert & Nancy Lynch)其實并沒有詳細解釋CAP三個單詞的具體含義,目前大家熟悉的解釋其實是另一個人(Robert Greiner)給出的。而且他還給出了兩版有所差異的解釋。
第二版解釋算是對第一版解釋的加強,他要加強的點主要是:
CAP描述的分布式系統,是互相連結并共享數據的節(jié)點的集合。因為其實并不是所有的分布式系統都會互連和共享數據。CAP理論是在涉及讀寫操作的場景下的理論,而不是分布式系統的所有功能。一致性只需要保障客戶端讀操作能讀到最新的寫操作結果,并不要求時時刻刻分布式系統的數據都是一致的,這是不現實的,只要保障客戶讀到的一致即可。可用性要求非故障的節(jié)點在合理的時間內能返回合理的響應,所謂合理是指非錯誤、非超時,即使數據不是最新的數據,也是合理的“舊數據”,是符合可用性的。分區(qū)容錯性要求網絡分區(qū)后系統能繼續(xù)履行職責,不僅僅要求系統不宕機,還要求能發(fā)揮作用,能處理業(yè)務邏輯。比如接口直接返回錯誤其實也代表系統在運行,但卻沒有履行職責。在分布式系統下,P(分區(qū)容忍)是必須選擇的,否則當分區(qū)后系統無法履行職責時,為了保障C(一致性),就要拒絕寫入數據,也就是不可用了。
在此基礎上,其實我們能選擇的只有C+P或者A+P,根據業(yè)務特性來選擇要優(yōu)先保障一致性還是可用性。
在選擇保障策略時,有幾個需要注意的點:
CAP關注的其實是數據的粒度,而不是整個系統的粒度,因此對于系統內的不同數據(對應不同子業(yè)務),其實是可以按照業(yè)務特性采取不同的CAP策略的。CAP實際忽略了網絡延遲,也就是允許數據復制過程中的短時間不一致,如果某些業(yè)務比如金融業(yè)務無法容忍這一點,那就只能對單個對象做單點寫入,其他節(jié)點備份,無法做多點寫入。但對于不同的對象,其實可以分庫來實現分布式。當沒有發(fā)生分區(qū)現象時,也就是不用考慮P時,上述限制就不存在,此時應該考慮如何保障CA。當發(fā)生分區(qū)后,犧牲CAP的其中一個并不代表什么都不用做,而是應該為分區(qū)后的恢復CA做準備,比如記錄分區(qū)期間的日志以供恢復時使用。伴隨CAP的一個退而求其次,也更現實的追求,是BASE理論,即基本可用,保障核心業(yè)務的可用性;軟狀態(tài),允許系統存在數據不一致的中間狀態(tài);最終一致性,一段時間后系統應該達到一致。
FMEA分析法:
要保障高可用,怎么下手呢?俗話說知己知彼才能有的放矢,因此做高可用的前提是了解系統存在怎樣的風險,并且還要識別出風險的優(yōu)先級,先治理更可能發(fā)生的、影響更大的風險。說得簡單,到底怎么做?業(yè)界其實已經提供了排查系統風險的基本方法論,即FMEA(Failure mode and effects analysis)——故障模式與影響分析。
FMEA的基本思路是,面對初始的架構設計圖,考慮假設其中某個部件發(fā)生故障,對系統會造成什么影響,進而判斷架構是否需要優(yōu)化。
具體來說,需要畫一張表,按照如下步驟逐個列出:
功能點:列出業(yè)務流程中的每個功能點。故障模式:量化描述該功能可能發(fā)生怎樣的故障,比如mysql響應時間超過3秒。故障影響:量化描述該每個故障可能導致的影響,但不用非常精確,比如20%用戶無法登錄。嚴重程度:設定標準,給每個影響的嚴重程度打分。故障原因:對于每個故障,考慮有哪些原因導致該故障。故障概率:對于每個原因,考慮其發(fā)生的概率,不用精確,分檔打分即可。風險程度:=嚴重程度 * 故障概率,據此就可以算出風險的處理優(yōu)先級了,肯定是程度分數越高的越應該優(yōu)先解決。已有措施、解決措施、后續(xù)規(guī)劃:用于梳理現狀,思考未來的改進方案等。基于上面這套方法論,可以有效地對系統的風險進行梳理,找出需要優(yōu)先解決的風險點,從而提高系統的可用性。
除了FMEA,其實還有一種應用更廣泛的風險分析和治理的理論,即BCP——業(yè)務連續(xù)性計劃,它是一套基于業(yè)務規(guī)律的規(guī)章流程,保障業(yè)務或組織在面對突發(fā)狀況時其關鍵業(yè)務功能可以持續(xù)不中斷。
相比FMEA,BCP除了評估風險及重要程度,還要求詳細地描述應對方案、殘余風險、災備恢復方案,并要求進行相應故障的培訓和演習安排,盡最大努力保障業(yè)務連續(xù)性。
知道風險在哪,優(yōu)先治理何種風險之后,就可以著手優(yōu)化架構。和高性能架構模式一樣,高可用架構也可以從存儲和計算兩個方面來分析。
3.2、存儲高可用
存儲高可用的本質都是通過將數據復制到多個存儲設備,通過數據冗余的方式來提高可用性。
雙機架構:
讓我們先從簡單的增加一臺機器開始,即雙機架構。
當機器變成兩臺后,根據兩臺機器擔任的角色不同,就會分成不同的策略,比如主備、主從、主主。
主備復制的架構是指一臺機器作為客戶端訪問的主機,另一臺機器純粹作為冗余備份用,當主機沒有故障時,備機不會被客戶端訪問到,僅僅需要從主機同步數據。這種策略很簡單,可以應對主機故障情況下的業(yè)務可用性問題,但在平常無法分擔主機的讀寫壓力,有點浪費。
主從復制的架構和主備復制的差別在于,從機除了復制備份數據,還需要干活,即還需要承擔一部分的客戶端請求(一般是分擔讀操作)。當主機故障時,從機的讀操作不會受到影響,但需要增加讀操作的請求分發(fā)策略,且和主備不同,由于從機直接提供數據讀,如果主從復制延遲大,數據不一致會對業(yè)務造成更明顯的影響。
對于主備和主從兩種策略,如果主機故障,都需要讓另一臺機器變成主機,才能繼續(xù)完整地提供服務,如果全靠人工干預來切換,會比較滯后和易錯,最好是能夠自動完成切換,這就涉及雙機切換的策略。
在考慮雙機切換時,要考慮什么?首先是需要感知機器的狀態(tài),是兩臺機器直連傳遞互相的狀態(tài),還是都傳遞給第三方來仲裁?所謂狀態(tài)要包含哪些內容才能定義一臺主機是故障呢?是發(fā)現一次問題就切換還是多觀察一會再切換?切換后如果主機恢復了是切換回來還是自動變備機呢?需不需要人工二次確認一下?
這些問題可能都得根據業(yè)務的特性來得出答案,此處僅給出三種常見的雙機切換模式:
互連式:兩臺機器直接連接傳遞信息,并根據傳遞的狀態(tài)信息判斷是否要切換主機,如果通道本身發(fā)生故障則無法判斷是否要切換了,可以再增加一個通道構成雙通道保障,不過也只是降低同時故障的概率。中介式:通過第三方中介來收集機器狀態(tài)并執(zhí)行策略,如果通道發(fā)生斷連,中介可以直接切換其他機器作為主機,但這要求中介本身是高可用的,已經有比較成熟的開源解決方案如zookeeper、keepalived。模擬式:備機模擬成客戶端,向主機發(fā)送業(yè)務類似的讀寫請求,根據響應情況來判斷主機的狀態(tài)決定是否要切換主機,這樣可以最真實地感受到客戶端角度下的主機故障,但和互連式不同,能獲取到的其他機器信息很少,容易出現判斷偏差。最后一種雙機架構是主主復制,和前面兩種只有一主的策略不同,這次兩臺都是主機,客戶端的請求可以達到任何一臺主機,不存在切換主機的問題。但這對數據的設計就有了嚴格的要求,如果存在唯一ID、嚴格的庫存數量等數據,就無法適用,這種策略適合那些偏臨時性、可丟失、可覆蓋的數據場景。
數據集群:
采用雙機架構的前提是一臺主機能夠存儲所有的業(yè)務數據并處理所有的業(yè)務請求,但機器的存儲和處理能力是有上限的,在大數據場景下就需要多臺服務器來構成數據集群。
如果是因為處理能力達到瓶頸,此時可以增加從機幫主機分擔壓力,即一主多從,稱為數據集中集群。這種集群方式需要任務分配算法將請求分散到不同機器上去,主要的問題在于數據需要復制到多臺從機,數據的一致性保障會比一主一從更為復雜。且當主機故障時,多臺從機協商新主機的策略也會變得復雜。這里有開源的zookeeper ZAB算法可以直接參考。
如果是因為存儲量級達到瓶頸,此時可以將數據分散存儲到不同服務器,每臺服務器負責存儲一部分數據,同時也備份一部分數據,稱為數據分散集群。數據分散集群同樣需要做負載均衡,在數據分區(qū)的分配上,hadoop采用獨立服務器負責數據分區(qū)的分配,ES集群通過選舉一臺服務器來做數據分區(qū)的分配。除了負載均衡,還需要支持擴縮容,此外由于數據是分散存儲的,當部分服務器故障時,要能夠將故障服務器的數據在其他服務器上恢復,并把原本分配到故障服務器的數據分配到其他正常的服務器上,即分區(qū)容錯性。
數據分區(qū):
數據集群可以在單臺乃至多臺服務器故障時依然保持業(yè)務可用,但如果因為地理級災難導致整個集群都故障了(斷網、火災等),那整個服務就不可用了。面對這種情況,就需要基于不同地理位置做數據分區(qū)。
做不同地理位置的數據分區(qū),首先要根據業(yè)務特性制定分區(qū)規(guī)則,大多還是按照地理位置提供的服務去做數據分區(qū),比如中國區(qū)主要存儲中國用戶的數據。
既然分區(qū)是為了防災,那么一個分區(qū)肯定不止存儲自身的數據,還需要做數據備份。從數據備份的策略來說,主要有三種模式:
集中式:存在一個總備份中心,所有的分區(qū)數據都往這個總中心備份,設計起來簡單,各個分區(qū)間沒有聯系,不會互相影響,也很容易擴展新的分區(qū)。但總中心的成本較高,而且總中心如果出故障,就要全部重新備份。互備式:每個分區(qū)備份另一個分區(qū)的數據,可以形成一個備份環(huán),或者按地理位置遠近來搭對備份,這樣可以直接利用已有的設備做數據備份。但設計較復雜,各個分區(qū)間需要聯系,當擴展新分區(qū)時,需要修改原有的備份線路。獨立式:每個分區(qū)配備自己的備份中心,一般設立在分區(qū)地理位置附近的城市,設計也簡單,各個分區(qū)間不會影響,擴展新分區(qū)也容易。但是成本會很高,而且只能防范城市級的災難。3.3、計算高可用
從存儲高可用的思路可以看出,高可用主要是通過增加機器冗余來實現備份,對計算高可用來說也是如此。通過增加機器,分擔服務器的壓力,并在單機發(fā)生故障的時候將請求分配到其他機器來保障業(yè)務可用性。
因此計算高可用的復雜性也主要是在多機器下任務分配的問題,比如當任務來臨(比如客戶端請求到來)時,如何選擇執(zhí)行任務的服務器?如果任務執(zhí)行失敗,如何重新分配呢?這里又可以回到前文說過的負載均衡相關的解法上。
計算服務器和存儲服務器在多機器情況下的架構是類似的,也分為主備、主從和集群。
主備架構下,備機僅僅用作冗余,平常不會接收到客戶端請求,當主機故障時,備機才會升級為主機提供服務。備機分為冷備和溫備。冷備是指備機只準備好程序包和配置文件,但實際平常并不會啟動系統。溫備是指備機的系統是持續(xù)啟動的,只是不對外提供服務,從而可以隨時切換主機。
主從架構下,從機也要執(zhí)行任務,由任務分配器按照預先定義的規(guī)則將任務分配給主機和從機。相比起主備,主從可以發(fā)揮一定的從機性能,避免成本空費,但任務的分配就變得復雜一些。
集群架構又分為對稱集群和非對稱集群。
對稱集群也叫負載均衡集群,其中所有的服務器都是同等對待的,任務會均衡地分配到每臺服務器。此時可以采用隨機、輪詢、Hash等簡單的分配機制,如果某臺服務器故障,不再給他分配任務即可。
非對稱集群下不同的服務器有不同的角色,比如分為master和slave。此時任務分配器需要有一定的規(guī)則將任務分配給不同角色的服務器,還需要有選舉策略來在master故障時選擇新的master。這個選舉策略的復雜度就豐儉由人了。
異地多活:
講存儲高可用已經說過數據分區(qū),計算高可用也有類似的高可用保障思路,歸納來說,它們都可以根據需要做異地多活,來提高整體的處理能力,并防范地區(qū)級的災難。異地多活中的”異地“,就是指集群部署到不同的地理位置,“活”則強調集群是隨時能提供服務的,不同于“備”還需要一個切換過程。
按照規(guī)模,異地多活可以分為同城異區(qū)、跨城異地和跨國異地。顯而易見,不同模式下能夠應對的地區(qū)級故障是越來越高的,但同樣的,距離越遠,通信成本與延遲就越高,對通信通道可用性的挑戰(zhàn)也越高。因此跨城異地已經不適合對數據一致性要求非常高的業(yè)務,而跨國異地往往是用來給不同國家的用戶提供不同服務的。
由于異地多活需要花費很高的成本,極大地增加系統復雜度,因此在設計異地多活架構時,可以不用強求為所有業(yè)務都做異地多活,可以優(yōu)先為核心業(yè)務實現異地多活。盡量保障絕大部分用戶的異地多活,對于沒能保障的用戶,通過掛公告、事后補償、完善失敗提示等措施進行安撫、提升體驗。畢竟要做到100%可用性是不可能的,只能在能接受的成本下盡量逼近,所以當可用性達到一定瓶頸后,補償手段的成本或許更低。
在異地部署的情況下,數據一定會冗余存儲,物理上就無法實現絕對的實時同步,且距離越遠對數據一致性的挑戰(zhàn)越大,雖然可以靠減少距離、搭建高速專用網絡等方式來提高一致性,但也只是提高而已,因此大部分情況下, 只需考慮保障業(yè)務能接受范圍下的最終一致性即可。
在同步數據的時候,可以采用多種方式,比如通過消息隊列同步、利用數據庫自帶的同步機制同步、
通過換機房重試來解決同步延遲問題、通過session id讓同一數據的請求都到同一機房從而不用同步等。
可見,整個異地多活的設計步驟首先是對業(yè)務分級,挑選出核心業(yè)務做異地多活,然后對需要做異地多活的數據進行特征分析,考慮數據量、唯一性、實時性要求、可丟失性、可恢復性等,根據數據特性設計數據同步的方案。最后考慮各種異常情況下的處理手段,比如多通道同步、日志記錄恢復、用戶補償等,此時可以借用前文所說的FMEA等方法進行分析。
接口級故障:
前面討論的都是較為宏觀的服務器、分區(qū)級的故障發(fā)生時該怎么辦,實際上在平常的開發(fā)中,還應該防微杜漸,從接口粒度的角度,來防范和應對接口級的故障。應對的核心思路依然是優(yōu)先保障核心業(yè)務和絕大部分用戶可用。
對于接口級故障,有幾個常用的方法:限流、排隊、降級、熔斷。其中限流和排隊屬于事前防范的措施,而降級和熔斷屬于接口真的故障后的處理手段。
限流的目的在于控制接口的訪問量,避免被高頻訪問沖垮。
從限流維度來說,可以基于請求限流,即限制某個指標下、某個時間段內的請求數量,閾值的定義需要基于壓測和線上情況來逐步調優(yōu)。還可以基于資源限流,比如根據連接數、文件句柄、線程數等,這種維度更適合特殊的業(yè)務。
實現限流常用的有時間窗算法和桶算法。
時間窗算法分為固定時間窗和滑動時間窗。
固定時間窗通過統計固定時間周期內的量級來決定限流,但存在一個臨界點的問題,如果在兩個時間窗的中間發(fā)生超大流量,而在兩個時間窗內都各自沒有超出限制,就會出現無法被限流攔截的接口故障。因此滑動時間窗采用了部分重疊的時間統計周期來解決臨界點問題。
桶算法分為漏桶和令牌桶。
漏桶算法是將請求放入桶中,處理單元從桶里拿請求去進行處理,如果桶堆滿了就丟棄掉新的請求,可以理解為桶下面有個漏斗將請求往處理單元流動,整個桶的容量是有限的。這種模式下流入的速率取決于請求的頻率,當桶內有堆積的待處理請求時,流出速率是勻速的。漏桶算法適用于瞬時高并發(fā)的場景(如秒殺),處理可能慢一點,但可以緩存部分請求不丟棄。
令牌桶算法是在桶內放令牌,令牌數是有限的,新的請求需要先到桶里拿到令牌才能被處理,拿不到就會被丟棄。和漏桶勻速流出處理不同,令牌桶還能通過控制放令牌的速率來控制接收新請求的頻率,對于突發(fā)流量,可靠累計的令牌來處理,但是相對的處理速度也會突增。令牌桶算法適用于控制第三方服務訪問速度的場景,防止壓垮下游。
除了限流,還有一種控制處理速度的方法就是排隊。當新請求到來后先加入隊列,出隊端通過固定速度出隊處理請求,避免處理單元壓力過大。隊列也有長度限制,其機制和漏桶算法差不多。
如果真的事前防范真的被突破了,接口很可能或已經發(fā)生了故障,還能做什么呢?
一種手段是熔斷,即當處理量達到閾值,就主動停掉外部接口的訪問能力,這其實也是一種防范措施,對外的表現雖然是接口訪問故障,但系統內部得以被保護,不會引起更大的問題,待存量處理被消化完,或者外部請求減弱,或完成擴容后,再開放接口。熔斷的設計主要是閾值,需要按照業(yè)務特點和統計數據制定。
當接口故障后(無論是被動還是主動斷開),最好能提供降級策略。降級是丟車保帥,放棄一下非核心業(yè)務,保障核心業(yè)務可用,或者最低程度能提供故障公告,讓用戶不要反復嘗試請求來加重問題了。比起手動降級,更好的做法也是自動降級,需要具備檢測和發(fā)現降級時機的機制。
4、 可擴展架構模式
再回顧一遍互聯網行業(yè)的金科玉律:只有變化才是不變的。在設計架構時,一開始就要抱著業(yè)務隨時可能變動導致架構也要跟著變動的思想準備去設計,差別只在于變化的快慢而已。因此在設計架構時一定是要考慮可擴展性的。
在思考怎樣才是可擴展的時候,先想一想平常開發(fā)中什么情況下會覺得擴展性不好?大都是因為系統龐大、耦合嚴重、牽一發(fā)而動全身。因此對可擴展架構設計來說,基本的思想就是拆分。
拆分也有多種指導思想,如果面向業(yè)務流程來談拆分,就是分層架構;如果面向系統服務來談拆分,就是SOA、微服務架構;如果面向系統功能來拆分,就是微內核架構。
分層架構:
分層架構是我們最熟悉的,因為互聯網業(yè)務下,已經很少有純單機的服務,因此至少都是C/S架構、B/S架構,也就是至少也分為了客戶端/瀏覽器和后臺服務器這兩層。如果進一步拆分,就會將后臺服務基于職責進行自頂向下的劃分,比如分為接入層、應用層、邏輯層、領域層等。
分層的目的當然是為了讓各個層次間的服務減少耦合,方便進行各自范疇下的優(yōu)化,因此需要保證各層級間的差異是足夠清晰、邊界足夠明顯的,否則當要增加新功能的時候就會不知道該放到哪一層。各個層只處理本層邏輯,隔離關注點。
額外需注意的是一旦確定了分層,請求就必須層層傳遞,不能跳層,這是為了避免架構混亂,增加維護和擴展的復雜度,比如為了方便直接跨層從接入層調用領域層查詢數據,當需要進行統一的邏輯處理時,就無法切面處理所有請求了。
SOA架構:
SOA架構更多出現在傳統企業(yè)中,其主要解決的問題是企業(yè)中IT建設重復且效率低下,各部門自行接入獨立的IT系統,彼此之間架構、協議都不同,為了讓各個系統的服務能夠協調工作,SOA架構應運而生。
其有三個關鍵概念:服務、ESB和松耦合。
服務是指各個業(yè)務功能,比如原本各部門原本的系統提供的服務,可大可小。由于各服務之間無法直接通信,因此需要ESB,即企業(yè)服務總線進行對接,它將不同服務連接在一起,屏蔽各個服務的不同接口標準,類似計算機中的總線。松耦合是指各個服務的依賴需要盡量少,否則某個服務升級后整個系統無法使用就麻煩了。
這里也可以看出,ESB作為總線,為了對接各個服務,要處理各種不同的協議,其協議轉換耗費了大量的性能,會成為整個系統的瓶頸。
微服務:
微服務是近幾年最耳熟能詳的架構,其實它和SOA有一些相同之處,比如都是將各個服務拆分開來提供能力。但是和SOA也有一些本質的區(qū)別,微服務是沒有ESB的,其通信協議是一致的,因此通信管道僅僅做消息的傳遞,不理解內容和格式,也就沒有ESB的問題。而且為了快速交付、迭代,其服務的粒度會劃分地更細,對自動化部署能力也就要求更高,否則部署成本太大,達不到輕量快速的目的。
當然微服務雖然很火,但也不是解決所有問題的銀彈,它也會有一些問題存在。如果服務劃分的太細,那么互相之間的依賴關系就會變得特別復雜,服務數量、接口量、部署量過多,團隊的效率可能大降,如果沒有自動化支撐,交付效率會很低。由于調用鏈太長(多個服務),因此性能也會下降,問題定位會更困難,如果沒有服務治理的能力,管理起來會很混亂,不知道每個服務的情況如何。
因此如何拆分服務就成了每個使用微服務架構的團隊的重要考量點。這里也提供一些拆分的思路:
三個火槍手原則:考慮每三個人負責一個服務,互相可以形成穩(wěn)定的人員備份,討論起來也更容易得出結論,在此基礎上考慮能負責多大的一個服務?;跇I(yè)務邏輯拆分:最直觀的就是按邏輯拆分,如果職責不清,就參考三個火槍手原則確定服務大小?;诜€(wěn)定性拆分:按照服務的穩(wěn)定性分為穩(wěn)定服務和變動服務,穩(wěn)定服務粒度可以粗一些,變動服務粒度可以細一些,目的是減少變動服務之間的影響,但總體數量依然要控制?;诳煽啃圆鸱郑喊凑湛煽啃耘判颍蟾叩目梢圆鸺氁恍?,由前文可知,服務越簡單,高可用方案就會越簡單,成本也會越低。優(yōu)先保障核心服務的高可用?;谛阅懿鸱郑侯愃瓶煽啃裕阅芤笤礁叩?,拆出來單獨做高性能優(yōu)化,可有效降低成本。微服務架構如果沒有完善的基礎設施保障服務治理,那么也會帶來很多問題,降低效率,因此根據團隊和業(yè)務的規(guī)模,可以按以下優(yōu)先級進行基礎設施的支持:
優(yōu)先支持服務發(fā)現、服務路由、服務容錯(重試、流控、隔離),這些是微服務的基礎。接著支持接口框架(統一的協議格式與規(guī)范)、API網關(接入鑒權、權限控制、傳輸加密、請求路由等),可以提高開發(fā)效率。然后支持自動化部署、自動化測試能力,并搭建配置中心,可以提升測試和運維的效率。最后支持服務監(jiān)控、服務跟蹤、服務安全(接入安全、數據安全、傳輸安全、配置化安全策略等)的能力,可以進一步提高運維效率。微內核架構:
最后說說微內核架構,也叫插件化架構,顧名思義,是面向功能拆分的,通常包含核心系統和插件模塊。在微內核架構中,核心系統需要支持插件的管理和鏈接,即如何加載插件,何時加載插件,插件如何新增和操作,插件如何和核心引擎通信等。
舉一個最常見的微內核架構的例子——規(guī)則引擎,在這個架構中,引擎是內核,負責解析規(guī)則,并將輸入通過規(guī)則處理后得到輸出。而各種規(guī)則則是插件,通常根據各種業(yè)務場景進行配置,存儲到數據庫中。
5、總結
人們通常把某項互聯網業(yè)務的發(fā)展分為四個時期:初創(chuàng)期、發(fā)展期、競爭期和成熟期。
在初創(chuàng)期通常求快,系統能買就買,能用開源就用開源,能用的就是好的,先要活下來;到了發(fā)展期開始堆功能和優(yōu)化,要求能快速實現需求,并有余力對一些系統的問題進行優(yōu)化,當優(yōu)化到頂的時候就需要從架構層面來拆分優(yōu)化了;進入競爭期后,經過發(fā)展期的快速迭代,可能會存在很多重復造輪子和混亂的交互,此時就需要通過平臺化、服務化來解決一些公共的問題;最后到達成熟期后,主要在于補齊短板,優(yōu)化弱項,保障系統的穩(wěn)定。
在整個發(fā)展的過程中,同一個功能的前后要求也是不同的,隨著用戶規(guī)模的增加,性能會越來越難保障,可用性問題的影響也會越來越大,因此復雜度就來了。
對于架構師來說,首要的任務是從當前系統的一大堆紛繁復雜的問題中識別出真正要通過架構重構來解決的問題,集中力量快速突破,但整體來說,要徐徐圖之,不要想著用重構來一次性解決所有問題。
對項目中的問題做好分類,劃分優(yōu)先級,先易后難,才更容易通過較少的資源占用,較快地得到成果,提高士氣。然后再循序漸進,每個階段控制在1~3個月,穩(wěn)步推進。
當然,在這個過程中,免不了和上下游團隊溝通協作,需要注意的是自己的目標和其他團隊的目標可能是不同的,需要對重構的價值進行換位思考,讓雙方都可以合作共贏,才能借力前進。
還是回到開頭的那句話,架構設計的主要目的是為了解決軟件系統復雜度帶來的問題。首先找到主要矛盾在哪,做到有的放矢,然后再結合知識、經驗進行設計,去解決面前的問題。
祝人人都成為一名合格的架構師。
標簽:
推薦文章
- 飯店內2萬余元黃金首飾被盜,3小時后警察找到了“最不可能的她”
- 為了防止造反,明朝不準王爺進京,清朝不準王爺出京,誰更高明
- 慈善夜市什么樣?來半淞浦西世博園區(qū)看看吧
- 蘭州市出臺《關于進一步促進房地產市場平穩(wěn)健康發(fā)展的若干措施》
- ?荷乙戰(zhàn)報:赫爾肯斯頭槌制勝 威廉二世2-1逆轉馬斯特里赫特
- 四合院開局一只旅行青蛙(旅行青蛙 明信片)
- 詹寧斯談明年奧運首發(fā):庫里、布克、詹姆斯、杜蘭特、濃眉
- 東西問·漢學家丨美國漢學家邰謐俠:《道德經》緣何成為外譯最多的中國典籍?
- 順發(fā)恒業(yè)(000631.SZ):選舉許小建為董事長
- 非遺文化+群眾體育!普寧連續(xù)24年舉辦7屆運動會
- 13歲女孩被老師扇致耳膜穿孔,事發(fā)數月老師仍在上課,學?;貞?/a>
- 楊冪男友曝光?周冬雨跑路?杜華背刺孟美岐?檀健次被代言退貨?
- 2023內蒙古鄂爾多斯市黨群部門所屬事業(yè)單位招聘工作人員考試成績匯總的公告
- 祥源新材(300980.SZ):研發(fā)生產的聚烯烴發(fā)泡材料已進入華為的供應鏈體系中,通過下游模切廠供給至華為
- 免票、半價!徐州最新發(fā)布!
- 華為Mate60和Mate50配置對比!5499起“加量不加價”
- 軒尼詩Hennessy亞洲首店將于上海前灘太古里開業(yè)
- 定西寬粉“圈粉”無數
- 河南各級工會三年消費援疆超4.5億元
- 謹防文具盲盒“刺傷”孩子
- 一天三場重磅活動 溫州新能源產業(yè)風鼓滿帆
- 愛柯迪(600933)8月31日主力資金凈賣出1283.43萬元
- 機械革命鯊瘋了 R7-7840H迷你主機2999元!
- 中貝通信:算力租賃業(yè)務尚未產生收入
- 金輝控股上半年凈利潤約7.37億元,二線及核心三線土儲占比為97%
- 街邊煙火氣聚攏起人氣和財氣
- 崩壞星穹鐵道往復不止怎么達成
- 蘇州五批次共計成交金額42.9億元,2宗地塊封頂搖號
- 華泰證券(06886):“21華泰11”將于9月7日付息
- 宣戰(zhàn)書(關于宣戰(zhàn)書介紹)
- 離婚后對方不給撫養(yǎng)費可以申請法院強制執(zhí)行嗎?
- 中國智能手表市場:華為居首 蘋果、小米居二
- 中央氣象臺升級發(fā)布臺風紅色預警
- 吳子嘉曝郭民調再往下掉 沒能力就不要玩了
- 阿特斯:8月30日融資買入2477萬元,融資融券余額2.86億元
- 180家上市公司中報分紅,減持新規(guī)下3家“鐵公雞”終分紅
- 今日中國組合timez組合解散了嗎(能說實話嗎 TimeZ和EXO那個人氣更高呢為什么我覺得TimeZ有些弱呢)
- 治安管理處罰法修訂草案首次提請審議,這些看點值得關注
- 強度堪比“杜蘇芮”!新臺風會影響江西!接下來天氣……
- 龍湖集團2023年第一期中期票據成功發(fā)行,規(guī)模為11億元
- 四箭齊發(fā),大牛市來了?
- |不一樣的新村民,舞出岱岳新風情
- 萊西格(關于萊西格的簡介)
- 良品鋪子行走的CD夏日歌會落地武漢美術館,本周五將迎來收官之戰(zhàn)
- 中集集團上半年營收606億元 儲能業(yè)務在手訂單逾10億元
- 天風證券:給予科前生物買入評級
- 國產芯片制造的突破手,青島芯恩-澳柯瑪
- 農業(yè)農村部:科學規(guī)范開展增殖放流 推進長江大保護工作
- 福田雷薩北方戰(zhàn)區(qū)營銷業(yè)務交流會圓滿召開
- 奮力奪取秋糧好收成
- 【動脈嚴選新品鑒第27期】安速康醫(yī)療:首款國產分體式設計無主機超聲刀
- AH300ETF:融資凈償還1.15萬元,融資余額97.29萬元(08-29)
- 食品安全板塊8月29日漲1.78%,新 大 陸領漲,主力資金凈流出1.11億元
- 創(chuàng)建文明城市從我做起征文800字開頭 創(chuàng)建文明城市從我做起征文
- [meteortale]被收養(yǎng)的姐弟 Mokiet&Undyne
- 海綿是什么材料做的(海綿是什么材料)
- 皮蛋“拌”香蕉 沉浸式藝術展登陸上海
- 曝北京首鋼男籃下賽季季后賽主場定在首都體育館
- 收評:兩市收高創(chuàng)業(yè)板指漲近3% 科創(chuàng)50指數大漲超4% 資金爆買相關ETF
- 莫里斯·斯泰因(關于莫里斯·斯泰因簡述)
- 生物醫(yī)藥產業(yè)高質量發(fā)展戰(zhàn)略咨詢會召開
- 北京來論:兩岸經貿關系必須回歸正?;壍?/a>
- 中國電研:8月28日融資買入445.01萬元,融資融券余額1.06億元
- 襄陽市樊城區(qū)明晶巷社區(qū):打造睦鄰調解室,巧化百姓煩心事
- 浙能電力:8月28日融資買入2202.59萬元,融資融券余額2.4億元
- 國海證券給予馬應龍買入評級,2023 年中報點評:基數影響上半年銷售費用高增長,短期拖累利潤端
- 殘保金2019年2015號優(yōu)惠政策(殘保金2019)
- 財政部、國家稅務總局公布延續(xù)一批個人所得稅優(yōu)惠政策
- 自行車和棒球來了!明天10點,杭州亞運會又有8個項目開票
- 國家二級保護動物雨中“落難”,警民聯手救助
- 【互動掘金】泰勝風能:目前在手訂單充裕 各生產基地產能利用較為飽滿
- 二維碼 推動數字時代發(fā)展新變革
- 公安河東分局開展平安建設主題宣傳活動
- 券商觀點|食品飲料行業(yè)研究周報:中國啤酒的高端化,道阻且長,溯游從之
- 暴雨將至!臺風“蘇拉”逐漸靠近,海南未來天氣
- 瑞爾特8月28日快速反彈
- 悄無聲息的意思(別具匠心的意思)
- “不只選好作品,更要選好苗子”——2023青創(chuàng)賽側記
- 【碧藍檔案×明日方舟】當羅德島誤入基沃托斯27:初入灰雞窩的日富美
- 發(fā)泄小游戲下載(可以發(fā)泄的小游戲)
- 凱隱技能機制(lol凱隱技能)
- 中國石化:上半年凈利同比降20.1% 擬8億至15億元回購股份
- 摩托羅拉耳機(關于摩托羅拉耳機的基本詳情介紹)
- “蘇拉”已升至超強臺風,預報路徑直指福建?未來泉州天氣……
- 睡前八個動作瘦小腿
- 紅樓夢:蘅蕪苑是大荒山?薛寶釵是山鬼轉世?
- qq涂鴉簡單畫法撩人(qq涂鴉怎么畫好看)
- 奧迪時間怎么設置(奧迪時間怎么調整?)
- 郭艾倫:開局心態(tài)調整的不錯&尤其張鎮(zhèn)麟 替補上來節(jié)奏有點停滯
- 盤古越獄工具怎么用(盤古越獄工具)
- Target推進布局區(qū)域物流網絡 提供就近配送服務
- 科威爾(688551.SH):擬使用不超4.5億元暫時閑置募集資金進行現金管理
- 老師補課學生提高60分,家長明知違規(guī)卻引而不發(fā),原來是時機未到
- 多措并舉促消費丨稅惠扮靚夜經濟
X 關閉
資訊
- 公募基金數量突破一萬大關下半年新基金發(fā)行或將提速
- 嫦娥五號帶回近2公斤月球巖石 揭示月球進化歷史
- 最新研究發(fā)現 新冠肺炎在幼兒中出現一種前所未見并發(fā)癥
- 澳大利亞研究人員 發(fā)現調節(jié)受損神經修復分子機制
- 我國古代美容護膚品多為中醫(yī)配方 且在清代十分成熟
- 直擊山西烏馬河漫堤救援現場
- 剪影式牦牛、綬帶鳥、盤羊……藏北鑿刻巖畫中的精靈背后藏著這些秘密
- 受熱帶低壓影響 ??谌劭谕V棺鳂I(yè)
- 山西太原:持續(xù)降雨致路面塌坑 500余名“數字城管”冒雨巡查
- 浙江寧波援疆醫(yī)生如何度過國慶節(jié)?新疆大媽“點贊”
- 父子連續(xù)37年國慶同地合影 見證家國變遷
- 安徽馬鞍山廢棄礦山“變形記”:昔日千瘡百孔 如今生態(tài)優(yōu)先
X 關閉