雲中的資源相互都有關係。操作乙個資源通常會引發連鎖反應;例如,當刪除乙個集群的時候,是非常合理地去刪除屬於該集群的所有主機並停止所有在這些主機上執行的虛擬機器。傳統的iaas軟體要麼硬編碼連鎖反應,要麼簡單地禁止這些操作,例如,禁止使用者刪除有虛擬機器執行的集群。zstack提供乙個級聯框架,用以散布本來只對乙個資源的操作到所有相關的資源。資源可以通過實現乙個簡單的擴充套件點以加入級聯框架,使得資源的業務邏輯與框架解耦。
動機
雲中的資源多多少少都彼此依賴;例如,乙個主機是乙個集群的子資源,乙個主儲存是乙個集群的兄弟資源,l3網路是乙個區域的後裔資源。資源之間的關係可以被描述為乙個有向圖:
上圖,我們展示了zstack的主要資源;不同的iaas軟體可能使用不同的術語,上圖主要是想讓你有乙個粗略的概念。由上圖所暗示的,當對資源進行操作時,不僅僅是目標資源,相關資源也將受到影響;例如,當刪除乙個區域時,比較理想的是屬於區域的集群、主機、主儲存、l2網路等資源也同時被刪除。為了處理這個問題,iaas軟體必須滿足級聯(cascading)操作的需求。
問題大多數iaas軟體很少考慮級聯操作。它們要麼硬編碼業務邏輯,例如,你需要顯式刪除乙個將要被刪除帳戶的所有資源;要麼直接不允許這種操作,例如,當你試圖刪除乙個ip位址範圍時,丟擲乙個錯誤資訊「仍有vm使用在這個ip範圍中的ip」。這兩種方法都會帶來很多麻煩。對硬編碼而言,它使軟體不能靈活的新增新的資源,因為你必須修改現有的**來新增級聯操作,例如,修改刪除帳戶的**使得賬戶刪除時,新資源也被刪除。對於完全沒有責任感的錯誤資訊,使用者要麼去做無聊的工作,例如,在刪除乙個ip範圍之前,手動刪除100個虛擬機器;要麼摧毀現有的一切,然後從零開始,例如,重新部署整個雲。
避免誤操作不是藉口:有些人可能會聲稱不允許級聯刪除是慎重考慮的結果,因為使用者可能會誤操作,誤操作可能帶來災難性的後果;例如,錯誤地刪除區域會導致損失掉所有虛擬機器。然而,這種說法只是乙個錯誤的藉口,並且是一種為使用者做決定的自作聰明。你能想象嗎,當你為了刪除乙個區域必須手動刪除10,000個虛擬機器,因為軟體認為你可能會做錯事,所以迫使你枯燥的重複10,000次任務確認?乙個好的軟體應該為使用者提供選擇,並讓他們做出決定。在我們的例子中,iaas軟體應該在進行到最後刪除之前警告使用者,還有10,000臺虛擬機器在執行;但一旦使用者承認他們需要這麼做,軟體就應該這麼做。
級聯框架
zstack通過乙個級聯框架解決這一問題;顧名思義,級聯框架允許乙個操作能從乙個資源級聯到其他資源。為了解耦整個架構,這個級聯框架被作為乙個單獨的元件創造出來,資源可以按意願加入框架。要加入框架,資源所需要做的全部事情就是實現乙個擴充套件點cascadeextensionpoint
(在我們的例子中abstractasynccascadeextension
是乙個實現cascadeextensionpoint的類):
class vmcascadeextension extends abstractasynccascadeextension else if (/*this is from deleting l3 network*/) else if (/* this is from deleting ip range*/) else if (/* this is from deleting host*/)
completion.success();
}@override
public listgetedgenames()
@override
public string getcascaderesourcename()
@override
public cascadeaction createactionforchildresource(cascadeaction action)
}
getcascaderesourcename()方法返回該資源的名稱(vminstance);getedgenames()方法返回乙個和資源直接關聯的資源名列表,在我們的例子中返回主儲存、l3網路、iprange和主機;所以如果刪除操作在這些edge resources或其上游資源(如區域)上發生時,該操作將被級聯至在getedgenames()方法中宣告了這些資源的擴充套件。級聯擴充套件可以在asynccascade() 中採取行動,並獲取必須的資訊比如操作碼(如刪除),根發起者(如區域,下文將很快給出解釋),作為操作**的父發起者(如主機,將很快給出解釋)和操作上下文(例如,哪台主機正在被刪除)。由於資源的關係是乙個可能有環路的有向圖,級聯框架將把圖壓扁成一棵樹,並把環路變為分支。例如,刪除區域的操作將最終建立以下樹(一部分):
注:如你所見,刪除區域操作將多次級聯到虛擬機器的級聯擴充套件;這是刻意的,因為級聯擴充套件通常依賴於父發起者去決定該採取什麼行動;在這個例子中,虛擬機器的父發起者為主儲存、主機、l3網路和ip範圍;然而,對於不同的父發起者,擴充套件可能會採取不同的行動;例如,如果父發起者為主儲存並且操作碼為delete
,該擴充套件將摧毀所有根雲盤在該主儲存的虛擬機器;但如果父發起者是主機,擴充套件將會只停止在那台主機上的虛擬機器,因為這些虛擬機器稍後就可以在其他主機上啟動。考慮到zstack沒有產生衝突的級聯操作,例如,不會有乙個操作導致虛擬機器在路徑a啟動而在路徑b停止,所以級聯操作從不同路徑進行多次延伸是沒有問題的。
當級聯乙個操作時,該框架從該操作被應用的root issuer開始;在上述刪除區域的示例中,zone
是根發起者;那麼框架將從根發起者遍歷樹,並呼叫擴充套件的createactionforchildresource()方法為每一條路徑上的每乙個擴充套件建立上下文;一旦所有上下文建立成功,該框架將再次遍歷樹,不過是從葉子節點到根,並呼叫每個擴充套件的asynccascade()方法;乙個擴充套件可以依靠父發起者去決定應該做哪些操作,父發起者在getedgenames()
方法中以資源名的方式宣告;例如,如果父發行者是主機,則停止虛擬機器;如果父發行者是主儲存,則刪除虛擬機器。
這兩個階段的遍歷保證,乙個操作(例如刪除)將只會被應用到根發起者,在所有下游資源都做完一些合適的操作後。例如,乙個區域只在所有子孫資源都被刪除後才能被刪除。
由於並不是所有的操作都需要級聯,乙個資源可以在它需要的時候直接呼叫cascadefacade.asynccascade()。
總結
在這篇文章中,我們演示了zstack的級聯框架,這是乙個強大的工具,用於擴散操作而不需要硬編碼。zstack用很多方式使用了它,除了我們在文中提到的以外,一些操作,如解除安裝主儲存(這將停止將被解除安裝的集群中的所有虛擬機器),解除安裝l2網路(這將停止將被解除安裝的集群中的所有虛擬機器)都是以這種方式實現的。有了它的幫助,管理員可以快速嘗試不同的雲部署而無需擔心不方便;你可以只刪除你的部署的一部分並重新建立乙個新的,而不需要僅因為你在乙個設計錯誤的l2網路上建立了許多虛擬機器,就重新部署整個雲(舉個例子)。
類似省市級聯的級聯選擇,乙個請求搞定
最近朋友遇到乙個需求 要做類似省市級聯的乙個東西,通過使用者選擇的年級,動態顯示對應的班級 年級的選項不是寫死的,而是由後台傳過來的資料動態顯示的 即頁面中的兩個下拉框 年級 班級,的選項均由資料庫提供,且班級的選項還受使用者已選擇的年級選項的影響 年級和班級在同一張表中 id年級id 年級班級id...
學院以及專業選擇框的級聯選擇
在學院資訊和專業資訊的獲取這有兩種可行方案,一種是分開獲取,先獲取學院,再根據學院獲取專業 另一種是直接獲取到整個學院跟專業的對映,然後根據這個來在前端進行展示,無需二次請求。這兩種方法各有利弊,但是在這裡,第一種方法是不可行的,因為我們是要在乙個列表裡面選擇專業,如果在分開獲取的話,會出現很多網路...
mysql中的級聯刪除和級聯置空和級聯更新
我就直接po 了,或者看我這篇 並茂版 mysql中的級聯刪除和級聯置空 create table nativeplace id int primary key auto increment comment 編號 province varchar 30 comment 省份 city varchar...