摘要:本文將對核心引擎的源碼進行剖析。在筆者看來,能夠快速迭代的原因首先是來自于每位工程師的辛勤付出。在中,還有一類很有意思的代碼,一般稱之為。筆者有機會將會在之后的系列文章分析其中的典型案例以及在代碼中使用極其頻繁的核心工具。
本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog...前言
ZStack是下一代開源的云計算IaaS(基礎架構(gòu)即服務)軟件。它主要面向的是未來的智能數(shù)據(jù)中心,通過提供的API來管理包括計算、存儲和網(wǎng)絡在內(nèi)的數(shù)據(jù)中心的各種資源。跟OpenStack相比,ZStack具有易用、穩(wěn)定、靈活、超高性能等特點。其單管理節(jié)點可以管理1萬臺物理機規(guī)模集群,多個管理節(jié)點構(gòu)建的集群可以做到使用一個數(shù)據(jù)庫、一套消息總線管理10萬臺物理機、數(shù)百萬個虛擬機節(jié)點、并發(fā)處理數(shù)萬個API。
以下是ZStackV2.2的服務架構(gòu)圖
官網(wǎng)地址:http://www.zstack.io/核心開源引擎ZStack GitHub:https://github.com/zstackio/z...
ZStack-Utility GitHub:https://github.com/zstackio/z...
閱讀源碼如果不想使用IDE,建議配合https://github.com/buunguyen/...。
本文將對核心引擎-ZStack的源碼進行剖析。在ZStack官網(wǎng)上我們可以看到其每個版本的發(fā)布都是攜帶了許多的新特性。在筆者看來,能夠快速迭代的原因首先是來自于每位工程師的辛勤付出。除此之外,因其還有些軟件工程領域中沉淀下來的最佳實踐:
良好的架構(gòu)設計
覆蓋較為全面的測試
恰當好處的使用設計模式
良好的架構(gòu)設計 異步架構(gòu)Iaas的核心應該做的是管控層,而不是數(shù)據(jù)層。故ZStack僅僅也是做出一些“決策”而已——在設計系統(tǒng)的時候,應不考慮在這些決策的執(zhí)行上消耗大量的資源。在面對大量請求或者“決策”的時候,如果使用多線程來處理阻塞式IO模型時會遇到一些問題:
阻塞模型的吞吐量受到線程池大小的限制;
創(chuàng)建并使用許多線程會耗費額外的時間用于上下文切換,影響系統(tǒng)性能。
而非阻塞、異步的消息驅(qū)動系統(tǒng)可以只運行少量的線程,并且不阻塞這些線程,只在需要計算資源時才使用它們。這大大提高了系統(tǒng)的響應速度,并且能夠更高效地利用系統(tǒng)資源。
故,ZStack采用了異步架構(gòu),分別由三個部分組成:
異步消息
異步方法
異步HTTP 請求
如果在系統(tǒng)中的一部分采用異步設計,是不行的。這樣還是會因為同步而沒法享受異步帶來的“福利”。故此整個系統(tǒng)都得采用異步架構(gòu)。
相對的,開發(fā)者們在編寫異步代碼的時候得格外小心。
在系統(tǒng)設計中,異步調(diào)用可以減少系統(tǒng)在IO上出現(xiàn)瓶頸的可能性。
擴展鏈接 : ZStack--可拓展性的秘密武器1:異步架構(gòu)無狀態(tài)服務
在ZStack中,每一個服務都是獨立存在的。為了方便的管理更多的物理機,ZStack推薦采用集群部署MN。但這樣就會遇到一個問題,不同MN下面有著不同的幾個服務存在,在這里我們設其為X個服務。在10個MN部署的情況下,可能就是10X個服務。那么在一個資源需要操作時,我需要發(fā)送向?qū)腗N。那么如何找到那個MN呢?最直觀的想法就是在各個MN中保存相應的“服務表”,這即是一種狀態(tài)。那么在分布式系統(tǒng)中,采用有狀態(tài)的服務絕對不是一個好的選擇,它會嚴重影響系統(tǒng)的擴展性。ZStack巧妙的采用了一致性哈希算法+MQ解決了這個問題。
這在系統(tǒng)設計中實為是一種使用一致性hash技術(shù)的負載均衡
擴展鏈接:ZStack—可拓展性秘密武器2:無狀態(tài)的服務無鎖架構(gòu)
解決并發(fā)的問題不一定要用顯式的鎖,也可以對同一資源做操作的任務做成隊列使其串行執(zhí)行。
注意:并發(fā) != 并行松耦合架構(gòu) 項目模塊化
擴展鏈接:ZStack--可拓展性秘密武器3:無鎖架構(gòu)
在Intellij中打開ZStack的代碼,會發(fā)現(xiàn)大多數(shù)目錄底下都會有一個pom.xml文件,ZStack采用了模塊化項目。模塊化的好處在工程實踐中不言而喻的,比如:
可以在不影響整個系統(tǒng)的情況下替換某個模塊
開發(fā)者只要專心的在自己的模塊中工作即可
減少系統(tǒng)耦合度,提高內(nèi)聚,減少資源循環(huán)依賴,增強系統(tǒng)框架設計
...
下面來看一下ZStack中代碼的結(jié)構(gòu):
代碼結(jié)構(gòu)截圖于2017.9.22
名稱 | 簡介 |
---|---|
build | 用于Java部分的編譯、打包、部署等 |
conf | 配置文件及SQL文件的放置;Spring Service配置存放;持久化文件配置 |
core | 核心模塊。實現(xiàn)系統(tǒng)的核心功能——包括數(shù)據(jù)庫、消息總線、工作流實現(xiàn)等等 |
coregroovy | ZStack的最新測試采用了Groovy,這里是對測試庫做的支持 |
header | 消息以及Entity的定義 |
plugin | 顧名思義。其中不少組件都以插件化開發(fā),提供較高的靈活性 |
sdk | 測試庫使用的SDK |
simulator | 對于測試庫支持的又一模塊,主要用戶simulator agent的行為 |
testlib | 測試庫 |
test | 測試模塊 |
工具類 | 工具包。目前僅僅支持了doc生成 |
utils | 代碼中使用的工具類 |
其他 | 功能實現(xiàn)模塊 |
在ZStack中,每個功能實現(xiàn)模塊都會被稱為服務——一個獨立的服務。各個服務之間的通信由MQ來承擔。這就像是傳統(tǒng)的CSE,C和E是不耦合的,通過S來交互。同樣的,一個服務需要向另一個服務發(fā)起調(diào)用,只需往消息總線發(fā)送消息,并指定這個服務ID(Service ID)即可。如果某個服務的代碼需要大量重構(gòu)或者做成微服務,只要提供相同的服務并注冊到MQ上就可以了。這就是事件驅(qū)動架構(gòu)(Event Driven Architecture)的一種典型實現(xiàn)。
CSE:Controller、Service、Entity。注:稱作Domain或者Model都是不專業(yè)的。Domain是一個領域?qū)ο螅覀冊僮鰝鹘y(tǒng)Java軟件web開發(fā)中,這些Domain都是貧血模型,是沒有行為的,或是沒有足夠的領域模型的行為的,所以,以這個理論來講,這些Domain都應該是一個普通的entity對象,并非領域?qū)ο螅哉埌寻臑?com.xxx.entity。
舉個簡單明了的例子。如果每個對象的行為都是通過消息來決定的(比如一個方法需要message得到回復后才能do something...),那么這個對象僅僅對消息總線產(chǎn)生了依賴。在測試中,將會發(fā)揮巨大的威力——我們只需要改變handle message處的行為,就可以使一個對象行為做出相應的變化。這樣可以使mock的單位變得更小,同時也可以變得更加靈活。
試想如果通過函數(shù)調(diào)用:
//方法a中的代碼 xxService.method1(); xx2Service.method2();
在測試中該如何解耦?但如果通過MQ——即一個消息來調(diào)用xxService.method1(),那么方法a對xxService就沒有了直接的依賴。
使用Spring不了解Spring的人可以看:看起來很長但還是有用的Spring學習筆記
在代碼中,每當我們New出一個對象時,這個模塊便對這個對象產(chǎn)生了依賴。當我們需要測試的時候就不得不去Mock它。當依賴的對象or Field 有成千上萬個的時候,這就是一場災難了。代碼變得愈發(fā)不可測,坑就越多,開發(fā)者在擴展or維護項目的時候就會愈發(fā)的乏力。這就像是我們之前提到的MQ,服務1->MQ->服務2,由于中間隔了一個MQ,于是服務1和服務2沒有必然的關系。同樣的,從對象1->調(diào)用->對象2到對象1->調(diào)用->Spring提供的IOC容器->對象2,這樣使對象與對象之間也沒有了直接調(diào)用關系,對象1只要知道它要調(diào)用的對象實現(xiàn)了其需要的Interface就是可以調(diào)用的。
除了Autowired的正確使用姿勢。在ZStack中,還有一類很有意思的代碼,一般稱之為xxxExtensionPoint。其本質(zhì)就是定義一個接口,然后其實現(xiàn)類作為Bean通過XML注冊到IOC中。在需要使用的時候,通過Spring獲取到所有實現(xiàn)該接口的對象,調(diào)用其函數(shù)。這樣就會使代碼變得非常的靈活。
例如,ZStack分為多個版本——開源版、企業(yè)版、混合云版等。如果一個服務在不同版本中的處理邏輯需要稍許不同,那么就可以在開源版的代碼中注冊一個接口,在另一個版本的服務中實現(xiàn)該接口。這樣也不會影響到開源版的原有邏輯。從模塊上看我們代碼的是松耦合并且無法直接調(diào)用的,但是在內(nèi)存中,卻是可以調(diào)用得到的。
覆蓋較為全面的測試在ZStack中
開發(fā)者Fix每一個Bug都是需要補充相應的Case;
每一個Feature在進去之前更會由開發(fā)工程師與QA工程師同時制定測試場景并Cover;
每一個PR(pull request)進去之前都會通過PR系統(tǒng)跑過所有的Case,以防止Bug的Regression;
由于ZStack源碼做到了一定的解耦合(上述提到)與無狀態(tài),使得集成測試得以進行。
其首席架構(gòu)師Frank.Zhang曾說過:我們開發(fā)者在寫代碼的時候往往就應該考慮該怎么寫測試了。恰當好處的使用設計模式想了解ZStack的測試框架,可以看: ZStack WiKi :管理節(jié)點基于模擬器的Integration Test框架
在ZStack中,設計模式有較為良好的實踐。筆者有機會將會在之后的系列文章分析其中的典型案例以及在代碼中使用極其頻繁的核心工具。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/25204.html
摘要:本文將對核心引擎的源碼進行剖析。在筆者看來,能夠快速迭代的原因首先是來自于每位工程師的辛勤付出。在中,還有一類很有意思的代碼,一般稱之為。筆者有機會將會在之后的系列文章分析其中的典型案例以及在代碼中使用極其頻繁的核心工具。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 ZStack是下一代開源的云計算IaaS(基礎架構(gòu)即服務)軟件。它...
摘要:本文將對核心引擎的源碼進行剖析。在筆者看來,能夠快速迭代的原因首先是來自于每位工程師的辛勤付出。在中,還有一類很有意思的代碼,一般稱之為。筆者有機會將會在之后的系列文章分析其中的典型案例以及在代碼中使用極其頻繁的核心工具。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 ZStack是下一代開源的云計算IaaS(基礎架構(gòu)即服務)軟件。它...
摘要:下面將開始分析它的源碼。僅僅定義了一個最小應有的行為。更好的選擇由于該庫是為定制而生,故此有一些防御性判斷,源碼顯得略為。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack(或者說產(chǎn)品化的IaaS軟件)中的任務通常有很長的執(zhí)行路徑,錯誤可能發(fā)生在路徑的任意一處。為了保證系統(tǒng)的正確性,需提供一種較為完善的回滾機制——在ZSt...
摘要:但新增模塊的結(jié)構(gòu)卻還是大致相同,此即是的經(jīng)典設計模式這套模式也被開發(fā)者稱為三駕馬車。領域?qū)佣x負責表達業(yè)務概念,業(yè)務狀態(tài)信息以及業(yè)務規(guī)則。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 隨著ZStack的版本迭代,其可以掌管的資源也越來越多。但新增模塊的結(jié)構(gòu)卻還是大致相同,此即是ZStack的經(jīng)典設計模式——這套模式也被開發(fā)者稱為ZS...
摘要:但在實際的二次開發(fā)中,這些做法未必能夠完全滿足需求。在源碼剖析之核心庫鑒賞一文中,我們了解到是的基礎設施之一,同時也允許通過顯示聲明的方式來聲明。同理,一些也可以使用繼承進行擴展。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack博文-5.通用插件系統(tǒng)中,官方提出了幾個較為經(jīng)典的擴展方式。但在實際的二次開發(fā)中,這些做法未必...
閱讀 2102·2023-04-26 00:09
閱讀 3129·2021-09-26 10:12
閱讀 3497·2019-08-30 15:44
閱讀 2869·2019-08-30 13:47
閱讀 928·2019-08-23 17:56
閱讀 3234·2019-08-23 15:31
閱讀 480·2019-08-23 13:47
閱讀 2517·2019-08-23 11:56