數(shù)據(jù)中心由多種資源組成,包括物理(如存儲、服務(wù)器)和虛擬(如虛擬機)。IaaS軟件本質(zhì)上是管理各種資源的狀態(tài);例如,創(chuàng)建虛擬機通常會改變存儲的狀態(tài)(在商店上創(chuàng)建新的磁盤)、網(wǎng)絡(luò)的狀態(tài)(在網(wǎng)絡(luò)上設(shè)置DHCP/DNS/NAT等)和虛擬狀態(tài)。機器管理程序(在虛擬機管理程序上創(chuàng)建)一個新的虛擬機。與普通應(yīng)用程序不同,大多數(shù)應(yīng)用程序管理存儲在內(nèi)存或數(shù)據(jù)庫中的狀態(tài)。為了反映數(shù)據(jù)中心的整體狀態(tài),IAAS軟件必須管理分散在每個設(shè)備中的狀態(tài),從而導(dǎo)致長的執(zhí)行路徑。IaaS軟件任務(wù)通常涉及多個設(shè)備上的狀態(tài)改變,在任何步驟都可能發(fā)生錯誤,然后系統(tǒng)處于中間狀態(tài),也就是說,一些設(shè)備已經(jīng)改變了狀態(tài),有些則沒有。例如,當(dāng)創(chuàng)建虛擬機時,用于配置IaaS軟件的VM網(wǎng)絡(luò)的常規(guī)步驟是DHCP DNS SNAT。如果在創(chuàng)建SNAT時發(fā)生錯誤,則先前配置的DHCP和DNS很可能保留在系統(tǒng)中,因為即使在最后沒有成功創(chuàng)建虛擬機,它們也已經(jīng)成功應(yīng)用。這種不一致的狀態(tài)通常會導(dǎo)致云層不穩(wěn)定。
另一方面,在傳統(tǒng)的IaaS軟件中,硬編碼的業(yè)務(wù)邏輯是不靈活的,為了改變,開發(fā)人員經(jīng)常不得不重寫或修改現(xiàn)有代碼來改變某些已建立的行為,從而影響軟件的穩(wěn)定性。
解決這些問題的方法是引入工作流的概念,將整個業(yè)務(wù)邏輯分解成細粒度的回滾步驟,以便軟件能夠清理生成的錯誤的狀態(tài)并使軟件可配置。
注意:在ZStad中,我們可以調(diào)用工作流“流程”中的步驟,在下面的文章中,流程(流程)和步驟(步驟)是可互換的。
問題
錯誤處理一直是軟件設(shè)計中的頭疼問題。即使現(xiàn)在每個軟件工程師都知道錯誤處理的重要性,但事實上,他們?nèi)匀辉谡医杩趤砗雎运?。巧妙的錯誤處理是困難的,特別是在任務(wù)可以跨多個組件的系統(tǒng)中。即使有經(jīng)驗的工程師能夠注意自己代碼中的錯誤,他們也不能為他們不寫的組件做出類似的努力,如果整個體系結(jié)構(gòu)不是強制性的,那么它可以以全局的方式增強錯誤處理的機制。忽略錯誤處理在IaaS軟件中尤其有害。不同于通過重新啟動恢復(fù)所有狀態(tài)的消費程序,IaaS軟件通常不能恢復(fù)其自身狀態(tài),并且將要求管理員手動在數(shù)據(jù)庫和外部設(shè)備中出錯。一個不一致的狀態(tài)可能不會導(dǎo)致任何大的問題,甚至可能不會被注意到,但是這種不一致狀態(tài)的持續(xù)積累最終會在某個時刻破壞整個云系統(tǒng)。
在這里相信有許多想要學(xué)習(xí)大數(shù)據(jù)的同學(xué),大家可以加下大數(shù)據(jù)學(xué)習(xí)群532218147,即可免費領(lǐng)取一整套系統(tǒng)的大數(shù)據(jù)學(xué)習(xí)教程
工作流引擎
工作流是一種將一些繁瑣的方法調(diào)用分解成細粒度的步驟,它集中在一件事情上。它由一個序列或狀態(tài)機驅(qū)動來完成一個完整的任務(wù)。在配置回滾處理程序之后,工作流在某個步驟發(fā)生錯誤或未處理異常時,可以中止執(zhí)行并回滾所有先前的執(zhí)行步驟。以創(chuàng)建虛擬機為例,主工作流看起來像:
序列工作流是由鏈式設(shè)計模式(鏈式模式)生成的,具有可預(yù)測的執(zhí)行序列,是ZStad工作流的基礎(chǔ)。一個流本質(zhì)上是一個可以包含子過程和后才可以完成以前所有的流程執(zhí)行java接口。
公共接口流{
空隙運行(FlowTrigger trigger,地圖數(shù)據(jù));
空隙回滾(FlowTrigger trigger,地圖數(shù)據(jù));
}
在流程界面中,當(dāng)工作流前進到這個過程(流程)時,將調(diào)用Run(FlowTrigger trigger,MAP數(shù)據(jù))方法;參數(shù)映射數(shù)據(jù)可以用來從先前的進程(流)獲得數(shù)據(jù),并將數(shù)據(jù)傳遞給后續(xù)的進程(流)。當(dāng)它完成時,進程(流程)調(diào)用ToGr.NeXT(引導(dǎo))工作流(工作流)來執(zhí)行下一個進程(流程);如果發(fā)生錯誤,進程(流)應(yīng)該調(diào)用TrutGel.Valt(ErrOrror Error)方法來中止執(zhí)行,并通知工作流(工作流)回滾完成。D流。進程(包括失敗的進程本身)調(diào)用它們各自的回滾()方法。
在FlowChain接口中建立的過程代表一個完整的工作流。創(chuàng)建FlowChain有兩種方法:
1。陳述式
該過程可以在組件的Spring配置文件中配置,并且可以通過向FlowChainBuilder填充進程的類名稱的列表來創(chuàng)建流程鏈。
這是創(chuàng)建包含可重用進程的嚴重可配置工作流的典型方法。在上面的示例中,該工作流的目的是創(chuàng)建用戶VM;所謂的應(yīng)用VM具有與分布式虛擬機網(wǎng)卡外部基本相同的相同進程,因此設(shè)備VM和用戶VM進程配置A的單個進程配置。最共享:
注意:在上一張圖片中,我們強調(diào)了Apple ServestMultLogATeNICFLUE流程為Green,這是創(chuàng)建用戶VM和VM應(yīng)用的工作流步驟的唯一不同地方。
2。程序設(shè)計方法
流程鏈也可以以編程方式創(chuàng)建。當(dāng)創(chuàng)建工作流是微不足道的,并且該過程是不可重用的時,通常使用此方法。
FuffChin鏈= FuffChin Buffeld. NeimSimple流鏈();
鏈表名稱(“測試”);
SeDATA(NeWHASMAP);
Chain.then(NeWFLASH){()
StrugIn NaMeEng= =“FLUT1”;
@重寫
Publicvoidrun(FlowTriggertrigger,MaDATA){
*做一些生意*/
Trigger.next();
}
@重寫
公共VoIP回滾(FlowTriggertrigger,MaDATA){
/*回滾某物*
Trigger.rollback();
}
“}”然后(NeWFLASH(){)
StrugIn NaMeEng= =“Fuff2”;
@重寫
Publicvoidrun(FlowTriggertrigger,MaDATA){
*做一些生意*/
Trigger.next();
}
@重寫
公共VoIP回滾(FlowTriggertrigger,MaDATA){
/*回滾某物*
Trigger.rollback();
}
“完成”(NeXFraveNeDebug(){)
@重寫
Publicvoidhandle(MaDATA){
*工作流已成功完成*
}
“}”.Nebug(NeXFraveRoWorkter)({)
@重寫
Publicvoidhandle(ErrorCodeerrCode,MaDATA){
*工作流失敗,錯誤*//
}
}啟動();
上述形式不方便使用,因為在流中,可以使用地圖數(shù)據(jù)來交換數(shù)據(jù),并且每個進程必須冗余地調(diào)用DATA GET()和DATA PUT()函數(shù)。在類似DSL的方式中,流可以通過變量共享數(shù)據(jù):
FuffChin鏈= FuffChin Buffeld.NexSealFuffon鏈();
鏈表名稱(“測試”);
Chain.then(NexSyfSt流()){()
StReDATA1=“數(shù)據(jù)可以被定義為類變量”;
{
DATA1=“數(shù)據(jù)可以在對象初始化器中進行初始化”;
}
@重寫
Publicvoidsetup(){
FialStReDATA2= =“數(shù)據(jù)也可以在方法范圍內(nèi)定義,但它卻”;
流(NeXFLUE){()
StrugIn NaMeEng= =“FLUT1”;
@重寫
Publicvoidrun(FlowTriggertrigger,MaDATA){
DATA1=“我們可以在這里改變數(shù)據(jù)”;
STRIGUSEDATA2=DATA2;
*做某事*
Trigger.next();
}
@重寫
公共VoIP回滾(FlowTriggertrigger,MaDATA){
*做一些回滾*
Trigger.rollback();
}
(});
流(NealNoRealFraceFuffy)({)
StrugIn NaMeEng= =“Fuff2”;
@重寫
Publicvoidrun(FlowTriggertrigger,MaDATA){
** DATA1是我們在流1**中改變的值。
STRIGUSEDATA1=DATA1;
*做某事*
Trigger.next();
}
(});
完成(NeXFruteNoDeLever)({)
@重寫
Publicvoidhandle(MaDATA){
*工作流已成功完成*
}
(});
錯誤(NeXFraveRoWorkter)({)
@重寫
Publicvoidhandle(ErrorCodeerrCode,MaDATA){
*工作流失敗,錯誤*//
}
(});
}
}啟動();
另外,大數(shù)據(jù)初學(xué)者有什么不懂的可以關(guān)注微信公眾號程序員大牛和轉(zhuǎn)發(fā)——我剛整理了一份大數(shù)據(jù)2018最新的0基礎(chǔ)入門和進階教程,無私分享