微服务编排引擎Cadence简介
原文來源:https://cadenceworkflow.io/
?
1、概述(Overview)
大量的用例跨越了單一的請(qǐng)求-應(yīng)答,需要跟蹤復(fù)雜的狀態(tài),響應(yīng)異步事件,并與外部不可靠的依賴項(xiàng)通信。構(gòu)建此類應(yīng)用程序的通常方法是將無狀態(tài)服務(wù)、數(shù)據(jù)庫、cron作業(yè)和隊(duì)列系統(tǒng)等大雜燴在一起。這對(duì)開發(fā)人員的開發(fā)效率產(chǎn)生了負(fù)面影響,因?yàn)榇蠖鄶?shù)代碼都是專門用于管道的,在大量低級(jí)細(xì)節(jié)后面隱藏了實(shí)際的業(yè)務(wù)邏輯。這樣的系統(tǒng)經(jīng)常存在可用性問題,因?yàn)楹茈y保持所有組件的健康。
Cadence解決方案是一種不考慮故障的有狀態(tài)編程模型,它掩蓋了構(gòu)建可伸縮分布式應(yīng)用程序的大部分復(fù)雜性。本質(zhì)上,Cadence提供了一個(gè)持久的虛擬內(nèi)存,它不鏈接到特定的進(jìn)程,并在各種主機(jī)和軟件故障中使用局部變量保存完整的應(yīng)用程序狀態(tài),包括函數(shù)堆棧。這允許您使用編程語言的全部功能編寫代碼,而Cadence則負(fù)責(zé)應(yīng)用程序的持久性、可用性和可伸縮性。
Cadence由編程框架(或客戶端庫)和托管服務(wù)(或后端)組成。該框架使開發(fā)人員能夠用熟悉的語言編寫和協(xié)調(diào)任務(wù)。
該框架使開發(fā)人員能夠用熟悉的語言編寫忽略錯(cuò)誤的代碼。
后端服務(wù)是無狀態(tài)的,依賴于持久存儲(chǔ)。目前支持Cassandra和MySQL存儲(chǔ)。可以添加到提供多行單碎片事務(wù)的任何其他數(shù)據(jù)庫的適配器。有不同的服務(wù)部署模型。在Uber,的團(tuán)隊(duì)運(yùn)營著由數(shù)百個(gè)應(yīng)用程序共享的多租戶集群。
2、使用案例(Use cases)
作為Cadence開發(fā)人員,我們面臨一個(gè)非技術(shù)性的難題:如何定位和描述Cadence平臺(tái)。
我們稱之為工作流。但是當(dāng)大多數(shù)人聽到“工作流”這個(gè)詞時(shí),他們會(huì)想到低代碼和ui。雖然這些可能對(duì)非技術(shù)用戶有用,但它們給軟件工程師帶來的痛苦往往大于價(jià)值。對(duì)于“hello world”演示應(yīng)用程序來說,大多數(shù)ui和低代碼DSL非常棒,但是任何包含100多個(gè)元素或幾千行JSON DSL的圖表都是完全不實(shí)際的。因此,將Cadence定位為一個(gè)工作流并不理想,因?yàn)樗鼤?huì)讓那些喜歡只使用代碼的開發(fā)人員望而卻步。
我們稱之為協(xié)調(diào)器。但這一術(shù)語相當(dāng)狹隘,并拒絕了希望實(shí)現(xiàn)業(yè)務(wù)流程自動(dòng)化解決方案的客戶。
我們稱之為耐用功能平臺(tái)。從技術(shù)上講,這是一個(gè)正確的術(shù)語。但微軟生態(tài)系統(tǒng)之外的大多數(shù)開發(fā)人員從未聽說過持久功能。
我們相信命名的問題來自這樣一個(gè)事實(shí):Cadence確實(shí)是一種編寫分布式應(yīng)用程序的新方法。它足夠通用,可以應(yīng)用于任何超出單個(gè)請(qǐng)求-回復(fù)的用例。它可以用于構(gòu)建工作流或編排平臺(tái)的傳統(tǒng)領(lǐng)域中的應(yīng)用程序。但對(duì)于傳統(tǒng)上依賴于數(shù)據(jù)庫和/或任務(wù)隊(duì)列的多個(gè)用例來說,這也是開發(fā)人員生產(chǎn)力的巨大提升。
2.1、定時(shí)輪詢(aka Distributed Cron)
定時(shí)輪詢,通常稱為分布式cron,是指定期執(zhí)行業(yè)務(wù)邏輯。對(duì)于這些場(chǎng)景,Cadence的優(yōu)勢(shì)在于它可以保證執(zhí)行、復(fù)雜的錯(cuò)誤處理、重試策略和對(duì)執(zhí)行歷史的可見性。
另一個(gè)重要的維度是規(guī)模。有些用例需要對(duì)大量的實(shí)體定期執(zhí)行。在Uber,有些應(yīng)用程序可以為每個(gè)客戶創(chuàng)建定期工作流。假設(shè)有1億多個(gè)并行cron作業(yè)不需要單獨(dú)的批處理框架。
定時(shí)輪詢通常是其他用例的一部分。例如,每月生成一次報(bào)告是定期的服務(wù)編排?;蛘呤且粋€(gè)事件驅(qū)動(dòng)的工作流,它為客戶累積忠誠度積分,并每月應(yīng)用一次這些積分。
有許多Cadence周期性執(zhí)行的例子。例如:
-
Uber后端服務(wù),每分鐘為每個(gè)城市的每個(gè)十六進(jìn)制重新計(jì)算各種統(tǒng)計(jì)數(shù)據(jù)。
-
每月優(yōu)步業(yè)務(wù)報(bào)告生成。
2.2、微服務(wù)編排和事務(wù)(Microservice Orchestration and Saga)
一些業(yè)務(wù)流程通常是以多個(gè)微服務(wù)調(diào)用的形式實(shí)現(xiàn)的。并且實(shí)現(xiàn)必須保證所有調(diào)用最終都必須成功,即使出現(xiàn)長期的下游服務(wù)故障。在某些情況下,應(yīng)該執(zhí)行補(bǔ)償回滾邏輯,而不是試圖通過長時(shí)間重試來完成過程。Saga模式是補(bǔ)償API標(biāo)準(zhǔn)化的一種方法。
Cadence非常適合這種情況。它保證工作流代碼最終完成,內(nèi)置了對(duì)無限指數(shù)活動(dòng)重試的支持,并簡化了補(bǔ)償邏輯的編碼。它還提供了對(duì)每個(gè)工作流狀態(tài)的完全可見性,與基于隊(duì)列的編排不同,在隊(duì)列中幾乎不可能獲得每個(gè)單獨(dú)請(qǐng)求的當(dāng)前狀態(tài)。
以下是一些基于Cadence的服務(wù)編排場(chǎng)景的真實(shí)示例:
-
使用Cadence工作流通過Banzai Cloud啟動(dòng)Kubernetes;
-
使用Uber的客戶困擾票務(wù)流程和編排引擎改善用戶體驗(yàn)
2.3、投票(Polling)
輪詢正在執(zhí)行定期操作,以檢查狀態(tài)更改。例如ping主機(jī)、調(diào)用restapi或?yàn)樾律蟼鞯奈募谐鯽mazons3存儲(chǔ)桶。
Cadence支持長時(shí)間運(yùn)行的活動(dòng)和無限制的重試,使它非常適合。
一些實(shí)際的用例:
-
網(wǎng)絡(luò)、主機(jī)和服務(wù)監(jiān)控;
-
正在處理上載到FTP或S3的文件;
-
輪詢外部API以使特定資源可用。
2.4、應(yīng)用事件驅(qū)動(dòng)( Event driven application)
許多應(yīng)用程序監(jiān)聽多個(gè)事件源,更新相應(yīng)業(yè)務(wù)實(shí)體的狀態(tài),并且在達(dá)到某種狀態(tài)時(shí)必須執(zhí)行操作。節(jié)奏是一個(gè)很好的適合其中許多。它直接支持異步事件(aka signals),有一個(gè)簡單的編程模型,可以掩蓋狀態(tài)持久性的許多復(fù)雜性,并通過內(nèi)置的重試確保外部操作的執(zhí)行。
一些實(shí)際的用例:
-
由消費(fèi)者行為檢測(cè)生成的對(duì)欺詐事件作出反應(yīng)的工作流;
-
客戶忠誠度計(jì)劃,其中工作流累積獎(jiǎng)勵(lì)點(diǎn)并在請(qǐng)求時(shí)應(yīng)用。
2.5、存儲(chǔ)掃描(Storage scan)
在大量主機(jī)或數(shù)據(jù)庫之間劃分大型數(shù)據(jù)集,或者在amazons3存儲(chǔ)桶中包含數(shù)十億個(gè)文件,這是很常見的。Cadence是一個(gè)理想的解決方案,可以以可伸縮和彈性的方式實(shí)現(xiàn)此類數(shù)據(jù)的完整掃描。標(biāo)準(zhǔn)模式是運(yùn)行一個(gè)活動(dòng)(或多個(gè)并行活動(dòng),用于分區(qū)數(shù)據(jù)集)來執(zhí)行掃描并將其進(jìn)度返回到Cadence。在主機(jī)發(fā)生故障的情況下,將在其他主機(jī)上重試該活動(dòng),并從上次報(bào)告的進(jìn)度繼續(xù)執(zhí)行。
一些實(shí)際的用例:
-
對(duì)所有工作流執(zhí)行記錄執(zhí)行定期掃描的Cadence內(nèi)部系統(tǒng)工作流。
2.6、批量任務(wù)(Batch job)
許多批處理作業(yè)不是純粹的數(shù)據(jù)操作程序。對(duì)于這些,現(xiàn)有的大數(shù)據(jù)框架是最合適的。但是,如果處理一個(gè)記錄需要外部API調(diào)用,而這些調(diào)用可能會(huì)失敗并且可能需要很長時(shí)間,那么Cadence可能會(huì)更好。
內(nèi)部Uber客戶使用Cadence生成月末報(bào)表。每個(gè)語句都需要調(diào)用多個(gè)微服務(wù),有些語句可能非常大。之所以選擇Cadence,是因?yàn)樗鼮樨?cái)務(wù)數(shù)據(jù)的持久性提供了嚴(yán)格的保證,并且能夠無縫地處理長時(shí)間運(yùn)行的操作、重試和間歇性故障。
2.7、基礎(chǔ)架構(gòu)資源調(diào)配(Infrastructure provisioning)
在公共云中提供一個(gè)新的數(shù)據(jù)中心或一個(gè)機(jī)器池是一個(gè)潛在的長時(shí)間運(yùn)行的操作,有很多可能出現(xiàn)間歇性故障。當(dāng)需要調(diào)配和配置幾十萬甚至幾十萬的資源時(shí),規(guī)模也是一個(gè)問題。對(duì)于資源調(diào)配場(chǎng)景,一個(gè)有用的特性是Cadence支持將活動(dòng)執(zhí)行路由到特定的進(jìn)程或主機(jī)。
許多操作都需要某種類型的鎖定,以確保一次對(duì)一個(gè)資源執(zhí)行的變異不超過一個(gè)。Cadence通過業(yè)務(wù)ID提供了強(qiáng)大的唯一性保證。這可用于以容錯(cuò)和可伸縮的方式實(shí)現(xiàn)此類鎖定行為。
一些實(shí)際的用例:
-
使用Cadence工作流啟動(dòng)Kubernetes,由Banzai Cloud提供;
-
在HashiCorp consur中使用Cadence編排集群生命周期。
2.8、部署(CI/CD and Deployment)
實(shí)現(xiàn)CI/CD管道并將應(yīng)用程序部署到容器、虛擬機(jī)或物理機(jī)是一個(gè)非常重要的過程。它的業(yè)務(wù)邏輯必須處理圍繞滾動(dòng)升級(jí)、金絲雀部署和回滾的復(fù)雜需求。Cadence是構(gòu)建部署解決方案的完美平臺(tái),因?yàn)樗峁┝怂斜匾谋WC和抽象,允許開發(fā)人員專注于業(yè)務(wù)邏輯。
一些實(shí)際的用例:
-
Uber內(nèi)部部署基礎(chǔ)設(shè)施;
-
更新推送至物聯(lián)網(wǎng)設(shè)備。
2.9、操作管理(Operational management)
假設(shè)您必須創(chuàng)建一個(gè)類似于amazonrds的自操作數(shù)據(jù)庫。Cadence用于多個(gè)項(xiàng)目,這些項(xiàng)目自動(dòng)管理和自動(dòng)恢復(fù)各種產(chǎn)品,如MySQL、Elasticsearch和apache Cassandra。
這種系統(tǒng)通常是不同用例的混合體。他們需要使用輪詢來監(jiān)視資源的狀態(tài)。它們必須對(duì)數(shù)據(jù)庫的管理接口執(zhí)行編排API調(diào)用。如果需要,他們必須提供新的硬件或Docker實(shí)例。他們需要推送配置更新,并定期執(zhí)行備份等其他操作。
2.10、交互式應(yīng)用程序(Interactive application)
Cadence的性能和可伸縮性足以支持交互式應(yīng)用程序。它可以用來跟蹤UI會(huì)話狀態(tài),同時(shí)執(zhí)行后臺(tái)操作。例如,在下訂單時(shí),當(dāng)后臺(tái)任務(wù)評(píng)估客戶是否存在欺詐行為時(shí),客戶可能需要經(jīng)過幾個(gè)屏幕。
2.11、DSL工作流(DSL workflows)
Cadence支持直接用Java和Go等編程語言實(shí)現(xiàn)業(yè)務(wù)邏輯。但有些情況下,使用特定領(lǐng)域的語言更合適?;蛘呖赡苡幸粋€(gè)遺留系統(tǒng)使用某種形式的DSL來定義流程,但它在操作上不穩(wěn)定且不可伸縮。這也適用于較新的系統(tǒng),如apacheflow、各種BPMN引擎和AWS Step函數(shù)。
可以使用Cadence SDK編寫解釋DSL定義的應(yīng)用程序。當(dāng)在Cadence上運(yùn)行時(shí),它會(huì)自動(dòng)變得高度容錯(cuò)、可伸縮和持久。Cadence已經(jīng)被用來抨擊一些Uber內(nèi)部的DSL引擎??蛻衾^續(xù)使用現(xiàn)有的流程定義,但Cadence被用作執(zhí)行引擎。
在Cadence之上統(tǒng)一所有公司的工作流引擎有很多好處。最明顯的一點(diǎn)是支持單個(gè)產(chǎn)品比支持多個(gè)產(chǎn)品更有效。它也很難擊敗Cadence的可伸縮性和穩(wěn)定性,這是它帶來的每一個(gè)集成。在某些情況下,共享引擎的能力可能會(huì)帶來巨大的好處。
2.12、大數(shù)據(jù)與ML(Big data and ML)
許多公司都構(gòu)建了定制的ETL和ML培訓(xùn)和部署解決方案。Cadence非常適合用于此類應(yīng)用的控制平面。
Cadence的一個(gè)重要特性是它能夠?qū)⑷蝿?wù)執(zhí)行路由到特定的進(jìn)程或主機(jī)。控制如何將ML模型和其他大文件分配給主機(jī)是很有用的。例如,如果一個(gè)ML模型是按城市劃分的,那么請(qǐng)求應(yīng)該被路由到包含相應(yīng)城市模型的主機(jī)上。
3、術(shù)語(Concepts)
Cadence是一種新的開發(fā)人員友好的分布式應(yīng)用程序開發(fā)方法。它借用了工作流自動(dòng)化領(lǐng)域的核心術(shù)語。所以它的概念包括工作流和活動(dòng)。工作流可以對(duì)事件作出反應(yīng)并通過查詢返回內(nèi)部狀態(tài)。
部署拓?fù)浣忉屃巳绾螌⑺羞@些概念映射到可部署的軟件組件。
3.1、工作流(WorkFlows)
Cadence核心抽象是一個(gè)忽略故障的有狀態(tài)工作流。工作流代碼的狀態(tài)(包括它創(chuàng)建的本地變量和線程)不受進(jìn)程和Cadence服務(wù)失敗的影響。這是一個(gè)非常強(qiáng)大的概念,因?yàn)樗庋b了狀態(tài)、處理線程、持久計(jì)時(shí)器和事件處理程序。
3.1.1、概述
Cadence核心抽象是一個(gè)忽略故障的有狀態(tài)工作流。工作流代碼的狀態(tài)(包括它創(chuàng)建的本地變量和線程)不受進(jìn)程和Cadence服務(wù)失敗的影響。這是一個(gè)非常強(qiáng)大的概念,因?yàn)樗庋b了狀態(tài)、處理線程、持久計(jì)時(shí)器和事件處理程序。
3.1.2、樣例
讓我們看一個(gè)用例??蛻糇?cè)了一個(gè)試用期的應(yīng)用程序。期滿后,如果客戶沒有取消,應(yīng)每月收取一次續(xù)費(fèi)。必須通過電子郵件通知客戶有關(guān)費(fèi)用,并應(yīng)能夠隨時(shí)取消訂閱。
這個(gè)用例的業(yè)務(wù)邏輯不是很復(fù)雜,可以用幾十行代碼來表達(dá)。但任何實(shí)際的實(shí)現(xiàn)都必須確保業(yè)務(wù)流程具有容錯(cuò)性和可伸縮性。設(shè)計(jì)這樣一個(gè)系統(tǒng)有多種方法。
一種方法是以數(shù)據(jù)庫為中心。應(yīng)用程序進(jìn)程將定期掃描數(shù)據(jù)庫表以查找處于特定狀態(tài)的客戶,執(zhí)行必要的操作,并更新狀態(tài)以反映這一點(diǎn)。雖然可行,但這種方法有各種缺點(diǎn)。最明顯的是客戶狀態(tài)的狀態(tài)機(jī)很快變得極其復(fù)雜。例如,向信用卡充值或發(fā)送電子郵件可能會(huì)由于下游系統(tǒng)不可用而失敗。失敗的調(diào)用可能需要長時(shí)間重試,最好使用指數(shù)重試策略。應(yīng)該對(duì)這些調(diào)用進(jìn)行限制,以避免外部系統(tǒng)過載。如果單個(gè)客戶記錄因任何原因無法處理,則應(yīng)支持毒丸,以避免阻塞整個(gè)流程?;跀?shù)據(jù)庫的方法通常也存在性能問題。對(duì)于需要對(duì)處于特定狀態(tài)的記錄進(jìn)行持續(xù)輪詢的情況,數(shù)據(jù)庫效率不高。
另一種常用的方法是使用計(jì)時(shí)器服務(wù)和隊(duì)列。任何更新都被推送到隊(duì)列中,然后從隊(duì)列中使用的工作線程更新數(shù)據(jù)庫,并可能在下游隊(duì)列中推送更多消息。對(duì)于需要調(diào)度的操作,可以使用外部計(jì)時(shí)器服務(wù)。這種方法通常可以擴(kuò)展得更好,因?yàn)閿?shù)據(jù)庫不會(huì)經(jīng)常被輪詢以獲取更改。但是它使得編程模型更加復(fù)雜和容易出錯(cuò),因?yàn)樵陉?duì)列系統(tǒng)和數(shù)據(jù)庫之間通常沒有事務(wù)更新。
使用Cadence,可以將整個(gè)邏輯封裝在一個(gè)簡單的持久函數(shù)中,該函數(shù)直接實(shí)現(xiàn)業(yè)務(wù)邏輯。因?yàn)楹瘮?shù)是有狀態(tài)的,所以實(shí)現(xiàn)者不需要使用任何額外的系統(tǒng)來確保持久性和容錯(cuò)性。
下面是實(shí)現(xiàn)訂閱管理用例的示例工作流。它是在Java中的,但也支持Go。Python和.NET庫正在進(jìn)行活動(dòng)開發(fā)。
public interface SubscriptionWorkflow {@WorkflowMethodvoid execute(String customerId); }public class SubscriptionWorkflowImpl implements SubscriptionWorkflow {private final SubscriptionActivities activities =Workflow.newActivityStub(SubscriptionActivities.class);@Overridepublic void execute(String customerId) {activities.sendWelcomeEmail(customerId);try {boolean trialPeriod = true;while (true) {Workflow.sleep(Duration.ofDays(30));activities.chargeMonthlyFee(customerId);if (trialPeriod) {activities.sendEndOfTrialEmail(customerId);trialPeriod = false;} else {activities.sendMonthlyChargeEmail(customerId);}}} catch (CancellationException e) {activities.processSubscriptionCancellation(customerId);activities.sendSorryToSeeYouGoEmail(customerId);}} }再次注意,這段代碼直接實(shí)現(xiàn)了業(yè)務(wù)邏輯。如果任何被調(diào)用的操作(aka活動(dòng))花費(fèi)了很長時(shí)間,那么代碼不會(huì)改變。如果下游處理服務(wù)停機(jī)那么長時(shí)間,可以在chargeMonthlyFee上阻塞一天。與阻止睡眠30天是工作流代碼中的正常操作相同的方法。
Cadence對(duì)開放工作流實(shí)例的數(shù)量幾乎沒有可伸縮性限制。因此,即使你的網(wǎng)站擁有數(shù)億消費(fèi)者,上述代碼也不會(huì)改變。
學(xué)習(xí)Cadence的開發(fā)人員經(jīng)常問的問題是“如何處理工作流中的工作流工作進(jìn)程失敗/重新啟動(dòng)”?答案是你不要這樣。工作流代碼完全不受任何工人或甚至Cadence服務(wù)本身的故障和停機(jī)的影響。一旦它們被恢復(fù),并且工作流需要處理某些事件(如計(jì)時(shí)器或活動(dòng)完成),工作流的當(dāng)前狀態(tài)將完全恢復(fù)并繼續(xù)執(zhí)行。工作流失敗的唯一原因是工作流業(yè)務(wù)代碼引發(fā)異常,而不是基礎(chǔ)架構(gòu)中斷。
另一個(gè)常見的問題是一個(gè)worker是否可以處理比其緩存大小或它可以支持的線程數(shù)更多的工作流實(shí)例。答案是,當(dāng)工作流處于阻塞狀態(tài)時(shí),可以安全地從工作線程中刪除。后來,當(dāng)需要(以外部事件的形式)出現(xiàn)時(shí),它可以在不同或相同的工人身上復(fù)活。因此,假設(shè)一個(gè)worker可以處理數(shù)百萬個(gè)開放的工作流執(zhí)行,假設(shè)它可以處理更新率。
3.1.3、狀態(tài)恢復(fù)和決策(State Recovery and Determinism)
工作流狀態(tài)恢復(fù)利用了事件源,它對(duì)代碼的編寫方式施加了一些限制。主要的限制是工作流代碼必須是確定性的,這意味著如果執(zhí)行多次,它必須產(chǎn)生完全相同的結(jié)果。這就排除了來自工作流代碼的任何外部API調(diào)用,因?yàn)橥獠空{(diào)用可以間歇性地失敗或隨時(shí)更改其輸出。這就是為什么所有與外部世界的交流都應(yīng)該通過活動(dòng)進(jìn)行。出于同樣的原因,工作流代碼必須使用Cadence api來獲取當(dāng)前時(shí)間、睡眠和創(chuàng)建新線程。
3.1.4、ID唯一性(ID Uniqueness)
工作流ID由客戶端在啟動(dòng)工作流時(shí)分配。它通常是一個(gè)業(yè)務(wù)級(jí)別的ID,如客戶ID或order ID。
Cadence保證在任何時(shí)候每個(gè)域都只能有一個(gè)具有給定ID的工作流(跨所有工作流類型)。嘗試啟動(dòng)具有相同ID的工作流將失敗,并出現(xiàn)WorkflowExecutionAlreadyStarted錯(cuò)誤。
如果存在具有相同ID的已完成工作流,則嘗試啟動(dòng)工作流取決于WorkflowIdReusePolicy選項(xiàng):
-
AllowDuplicateFailedOnly意味著只有在以前執(zhí)行的具有相同ID的工作流失敗時(shí),才允許啟動(dòng)工作流。
-
AllowDuplicate意味著它可以獨(dú)立于以前的工作流完成狀態(tài)啟動(dòng)。
-
RejectDuplicate表示根本不允許使用相同的工作流ID啟動(dòng)工作流執(zhí)行。
-
默認(rèn)值為AllowDuplicateFailedOnly。
為了區(qū)分具有相同工作流ID的多個(gè)工作流運(yùn)行,Cadence使用兩個(gè)ID標(biāo)識(shí)工作流:工作流ID和運(yùn)行ID。運(yùn)行ID是服務(wù)分配的UUID。準(zhǔn)確地說,任何工作流都是由三元組唯一標(biāo)識(shí)的:域名、工作流ID和運(yùn)行ID
3.1.5、子工作流( Child Workflow)
工作流可以作為子工作流執(zhí)行其他工作流:工作流:工作流:. 子工作流完成或失敗將報(bào)告給其父工作流。
使用子工作流的一些原因是:
-
子工作流可以由不包含父工作流代碼的一組單獨(dú)的工作線程托管。因此,它將充當(dāng)一個(gè)獨(dú)立的服務(wù),可以從多個(gè)其他工作流中調(diào)用。
-
單個(gè)工作流的大小有限。例如,它不能執(zhí)行100k活動(dòng)。子工作流可以用于將問題劃分為更小的塊。一個(gè)父母有1000個(gè)孩子,每個(gè)執(zhí)行1000個(gè)活動(dòng)是100萬個(gè)已執(zhí)行的活動(dòng)。
-
子工作流可用于使用其ID管理某些資源,以確保唯一性。例如,管理主機(jī)升級(jí)的工作流可以為每個(gè)主機(jī)有一個(gè)子工作流(主機(jī)名是工作流ID),并使用它們來確保主機(jī)上的所有操作都已序列化。
-
子工作流可用于執(zhí)行某些周期性邏輯,而不必放大父歷史記錄的大小。當(dāng)父級(jí)啟動(dòng)子級(jí)時(shí),它執(zhí)行周期性的邏輯調(diào)用,該調(diào)用根據(jù)需要繼續(xù)多次,然后完成。從父點(diǎn)if視圖來看,它只是一個(gè)子工作流調(diào)用。
與在單個(gè)工作流中并置所有應(yīng)用程序邏輯相比,子工作流的主要限制是缺少共享狀態(tài)。父級(jí)和子級(jí)只能通過異步信號(hào)進(jìn)行通信。但如果它們之間存在緊密耦合,那么使用單個(gè)工作流并僅依賴于共享對(duì)象狀態(tài)可能會(huì)更簡單。
我們建議從單個(gè)工作流實(shí)現(xiàn)開始,如果您的問題在已執(zhí)行活動(dòng)和已處理信號(hào)的數(shù)量方面有限制。它比多個(gè)異步通信工作流更直接
3.1.6、工作流重試(Workflow Retries)
工作流代碼不受基礎(chǔ)結(jié)構(gòu)級(jí)停機(jī)和故障的影響。但它仍然可能由于業(yè)務(wù)邏輯級(jí)別的故障而失敗。例如,活動(dòng)可能會(huì)由于超出重試間隔而失敗,并且應(yīng)用程序代碼或工作流代碼有錯(cuò)誤而無法處理該錯(cuò)誤。
有些工作流需要保證即使在出現(xiàn)此類故障的情況下也能保持運(yùn)行。為了支持此類用例,可以在啟動(dòng)工作流時(shí)指定可選的指數(shù)重試策略。如果指定了它,則工作流失敗將在計(jì)算的重試間隔之后從頭重新啟動(dòng)工作流。以下是重試策略參數(shù):
-
InitialInterval是第一次重試之前的延遲。
-
BackoffCoefficient。重試策略是指數(shù)型的。該系數(shù)指定重試間隔的增長速度。系數(shù)1表示重試間隔始終等于InitialInterval。
-
MaximumInterval指定重試之間的最大間隔。適用于系數(shù)大于1。
-
MaximumAttempts指定出現(xiàn)故障時(shí)嘗試執(zhí)行工作流的次數(shù)。如果超過此限制,則工作流將失敗而不重試。如果指定了ExpirationInterval,則不需要。
-
ExpirationInterval指定在出現(xiàn)故障時(shí)嘗試執(zhí)行工作流的時(shí)間。如果超過此間隔,則工作流將失敗而不重試。如果指定了MaximumAttempts,則不需要。
-
NonRetryableErrorReasons允許指定不應(yīng)重試的錯(cuò)誤。例如,在某些情況下,重試無效參數(shù)錯(cuò)誤是沒有意義的。
3.2、活動(dòng)(Activities)
無故障無狀態(tài)工作流代碼是Cadence的核心抽象。但是,由于確定性的執(zhí)行要求,它們不允許直接調(diào)用任何外部API。相反,它們協(xié)調(diào)活動(dòng)的執(zhí)行。在最簡單的形式中,Cadence活動(dòng)是受支持語言之一的函數(shù)或?qū)ο蠓椒āadence無法在失敗的情況下恢復(fù)活動(dòng)狀態(tài)。因此,活動(dòng)函數(shù)可以不受限制地包含任何代碼。
活動(dòng)通過任務(wù)列表異步調(diào)用。任務(wù)列表本質(zhì)上是一個(gè)隊(duì)列,用于存儲(chǔ)活動(dòng)任務(wù),直到它被可用的工作線程拾取為止。工作線程通過調(diào)用活動(dòng)的實(shí)現(xiàn)函數(shù)來處理活動(dòng)。當(dāng)函數(shù)返回時(shí),worker將結(jié)果報(bào)告給Cadence服務(wù),后者反過來通知工作流完成情況。通過從不同的流程完成活動(dòng),可以完全異步地實(shí)現(xiàn)該活動(dòng)。
3.2.1、超時(shí)(Timeouts)
Cadence不會(huì)對(duì)活動(dòng)持續(xù)時(shí)間施加任何系統(tǒng)限制。由應(yīng)用程序選擇執(zhí)行的超時(shí)。這些是可配置的活動(dòng)超時(shí):
-
ScheduleToStart是從工作流請(qǐng)求活動(dòng)執(zhí)行到工作人員開始執(zhí)行的最長時(shí)間。觸發(fā)此超時(shí)的通常原因是所有工作線程都已關(guān)閉或無法跟上請(qǐng)求速率。我們建議將此超時(shí)設(shè)置為工作流愿意在所有可能的工作進(jìn)程中斷的情況下等待活動(dòng)執(zhí)行的最長時(shí)間。
-
StartClose是活動(dòng)被工作線程選中后可以執(zhí)行的最長時(shí)間。
-
ScheduleToClose是從工作流請(qǐng)求執(zhí)行活動(dòng)到完成活動(dòng)的最長時(shí)間。
-
Heartbeat是Heartbeat請(qǐng)求之間的最長時(shí)間。請(qǐng)參閱長時(shí)間運(yùn)行的活動(dòng)。
需要ScheduleToClose或ScheduleToStart和StartClose超時(shí)。
3.2.2、重試(Retries)
由于Cadence無法恢復(fù)活動(dòng)的狀態(tài),而且它們可以與任何外部系統(tǒng)通信,因此會(huì)出現(xiàn)故障。因此,Cadence支持自動(dòng)活動(dòng)重試。當(dāng)任何關(guān)聯(lián)的策略都可以被調(diào)用時(shí)。以下是重試策略參數(shù):
-
InitialInterval是第一次重試之前的延遲。
-
BackoffCoefficient。重試策略是指數(shù)型的。該系數(shù)指定重試間隔的增長速度。系數(shù)1表示重試間隔始終等于InitialInterval。
-
MaximumInterval指定重試之間的最大間隔。適用于系數(shù)大于1。
-
MaximumAttempts指定出現(xiàn)故障時(shí)嘗試執(zhí)行工作流的次數(shù)。如果超過此限制,則工作流將失敗而不重試。如果指定了ExpirationInterval,則不需要。
-
ExpirationInterval指定在出現(xiàn)故障時(shí)嘗試執(zhí)行工作流的時(shí)間。如果超過此間隔,則工作流將失敗而不重試。如果指定了MaximumAttempts,則不需要。
-
NonRetryableErrorReasons允許指定不應(yīng)重試的錯(cuò)誤。例如,在某些情況下,重試無效參數(shù)錯(cuò)誤是沒有意義的。
有些情況下,失敗時(shí)不應(yīng)重試單個(gè)活動(dòng),而是應(yīng)重試整個(gè)工作流部分。例如,媒體編碼工作流將文件下載到主機(jī),對(duì)其進(jìn)行處理,然后將結(jié)果上載回存儲(chǔ)。在此工作流中,如果承載輔助進(jìn)程的主機(jī)死亡,則應(yīng)在其他主機(jī)上重試所有這三個(gè)活動(dòng)。這樣的重試應(yīng)該由工作流代碼處理,因?yàn)樗鼈兎浅L囟ㄓ谟美?/p>
3.2.3、長期運(yùn)行的活動(dòng)(Long Running Activities)
對(duì)于長時(shí)間運(yùn)行的活動(dòng),我們建議您指定相對(duì)較短的心跳超時(shí)和持續(xù)的心跳。這樣,即使是運(yùn)行很長時(shí)間的活動(dòng),也可以及時(shí)處理工作人員的故障。指定心跳超時(shí)的活動(dòng)應(yīng)定期從其實(shí)現(xiàn)中調(diào)用heartbeat方法。
心跳信號(hào)請(qǐng)求可以包括特定于應(yīng)用程序的有效負(fù)載。這對(duì)于保存活動(dòng)執(zhí)行進(jìn)度非常有用。如果某個(gè)活動(dòng)由于錯(cuò)過心跳而超時(shí),下一次嘗試執(zhí)行該活動(dòng)時(shí)可以訪問該進(jìn)度并從該點(diǎn)繼續(xù)執(zhí)行。
作為特長競(jìng)選活動(dòng)的領(lǐng)導(dǎo)者可以使用。節(jié)奏超時(shí)使用第二分辨率。因此,它不是實(shí)時(shí)應(yīng)用程序的解決方案。但是如果在幾秒鐘內(nèi)對(duì)流程失敗做出反應(yīng)是可以的,那么Cadence心跳活動(dòng)就是一個(gè)很好的選擇。
這種領(lǐng)導(dǎo)人選舉的一個(gè)常見用例是監(jiān)控?;顒?dòng)執(zhí)行一個(gè)內(nèi)部循環(huán),該循環(huán)定期輪詢某些API并檢查某些條件。它也在每次迭代中心跳。如果條件滿足,則活動(dòng)將完成,這將允許其工作流處理它。如果活動(dòng)工作線程死亡,則該活動(dòng)在超過檢測(cè)信號(hào)間隔后超時(shí),并在其他工作線程上重試。同樣的模式也適用于在amazons3存儲(chǔ)桶中輪詢新文件或REST或其他同步api中的響應(yīng)。
3.2.4、取消(Cancellation)
工作流可以請(qǐng)求取消活動(dòng)。目前,一項(xiàng)活動(dòng)被取消的唯一途徑是通過心跳。心跳信號(hào)請(qǐng)求失敗,并出現(xiàn)一個(gè)特殊錯(cuò)誤,指示活動(dòng)已取消。然后由活動(dòng)實(shí)現(xiàn)執(zhí)行所有必要的清理并報(bào)告已完成。由工作流實(shí)現(xiàn)決定是要等待活動(dòng)取消確認(rèn),還是不等待就繼續(xù)。
活動(dòng)心跳信號(hào)失敗的另一個(gè)常見情況是,調(diào)用它的工作流處于已完成狀態(tài)。在這種情況下,活動(dòng)也將執(zhí)行清理。
3.2.5、任務(wù)路由(Activity Task Routing through Task Lists)
活動(dòng)通過任務(wù)列表發(fā)送給工人。任務(wù)列表是工作人員監(jiān)聽的隊(duì)列。任務(wù)列表是高度動(dòng)態(tài)和輕量級(jí)的。它們不需要顯式注冊(cè)。每個(gè)工作進(jìn)程有一個(gè)任務(wù)列表是可以的。通過單個(gè)任務(wù)列表調(diào)用多個(gè)活動(dòng)類型是正常的。在某些情況下(如主機(jī)路由),在多個(gè)任務(wù)列表上調(diào)用相同的活動(dòng)類型是正常的。
以下是在單個(gè)工作流中使用多個(gè)活動(dòng)任務(wù)列表的一些用例:
-
流量控制。從任務(wù)列表中使用的工作線程僅在活動(dòng)任務(wù)具有可用容量時(shí)才請(qǐng)求該活動(dòng)任務(wù)。因此,請(qǐng)求峰值不會(huì)使工作人員過載。如果請(qǐng)求活動(dòng)執(zhí)行的速度比工作人員處理它們的速度快,則它們將被積壓在任務(wù)列表中。
-
節(jié)流。每個(gè)活動(dòng)工作線程都可以指定允許其處理任務(wù)列表中活動(dòng)的最大速率。即使它有備用容量,也不會(huì)超過這個(gè)限制。還支持全局任務(wù)列表速率限制。此限制適用于給定任務(wù)列表的所有工作線程。它經(jīng)常用于限制活動(dòng)調(diào)用的下游服務(wù)的負(fù)載。
-
獨(dú)立地部署一組活動(dòng)??紤]一個(gè)承載活動(dòng)的服務(wù),它可以獨(dú)立于其他活動(dòng)和工作流進(jìn)行部署。要將活動(dòng)任務(wù)發(fā)送到此服務(wù),需要一個(gè)單獨(dú)的任務(wù)列表。
-
具有不同能力的工人。例如,GPU盒上的工人與非GPU盒上的工人。在這種情況下,有兩個(gè)單獨(dú)的任務(wù)列表允許工作流選擇將執(zhí)行請(qǐng)求發(fā)送到哪個(gè)活動(dòng)。
-
將活動(dòng)路由到特定主機(jī)。例如,在媒體編碼的情況下,轉(zhuǎn)換和上載活動(dòng)必須與下載活動(dòng)在同一主機(jī)上運(yùn)行。
-
將活動(dòng)路由到特定進(jìn)程。例如,一些活動(dòng)加載大型數(shù)據(jù)集并在過程中緩存它。依賴于此數(shù)據(jù)集的活動(dòng)應(yīng)路由到同一進(jìn)程。
-
多重優(yōu)先權(quán)。每個(gè)優(yōu)先級(jí)一個(gè)任務(wù)列表,每個(gè)優(yōu)先級(jí)有一個(gè)工作池。
-
版本控制?;顒?dòng)的新的向后不兼容實(shí)現(xiàn)可能使用不同的任務(wù)列表。
3.2.6、異步活動(dòng)完成(Asynchronous Activity Completion)
默認(rèn)情況下,活動(dòng)是函數(shù)或方法,具體取決于客戶端庫語言。函數(shù)一返回,活動(dòng)就完成。但在某些情況下,活動(dòng)實(shí)現(xiàn)是異步的。例如,它通過消息隊(duì)列轉(zhuǎn)發(fā)到外部系統(tǒng)。而回復(fù)來自另一個(gè)隊(duì)列。
為了支持這樣的用例,Cadence允許在活動(dòng)函數(shù)完成時(shí)不完成的活動(dòng)實(shí)現(xiàn)。在這種情況下,應(yīng)該使用單獨(dú)的API來完成活動(dòng)。這個(gè)API可以從原始活動(dòng)工作人員使用的任何進(jìn)程調(diào)用,即使是在不同的編程語言中也是如此。
3.2.7、本地活動(dòng)(Local Activities)
有些活動(dòng)的生命周期很短,不需要查詢語義、流量控制、速率限制和路由功能。對(duì)于這些節(jié)奏支持所謂的局部活動(dòng)特征。本地活動(dòng)與調(diào)用它們的工作流在同一工作進(jìn)程中執(zhí)行??紤]將本地活動(dòng)用于以下功能:
-
不超過幾秒鐘。
-
不需要全局速率限制。
-
不需要路由到特定的工作線程或工作線程池。
-
可以在與調(diào)用它們的工作流相同的二進(jìn)制文件中實(shí)現(xiàn)。
本地活動(dòng)的主要好處是,與通常的活動(dòng)調(diào)用相比,本地活動(dòng)在利用Cadence服務(wù)資源方面效率更高,延遲開銷也更低。
3.3、事件處理(Event handling)
忽略故障的有狀態(tài)工作流可以在外部事件時(shí)發(fā)出信號(hào)。信號(hào)始終是指向特定工作流實(shí)例的點(diǎn)對(duì)點(diǎn)。信號(hào)總是按照接收的順序進(jìn)行處理。
有多種情況下信號(hào)是有用的。
3.3.1、事件聚合和關(guān)聯(lián)(Event Aggregation and Correlation)
Cadence并不是ApacheFlink或ApacheSpark這樣的通用流處理引擎的替代品。但在某些情況下,它更適合。例如,當(dāng)所有應(yīng)該聚合和關(guān)聯(lián)的事件總是應(yīng)用于具有清晰ID的某個(gè)業(yè)務(wù)實(shí)體時(shí),然后當(dāng)滿足某個(gè)條件時(shí),應(yīng)該執(zhí)行操作。
主要的限制是單個(gè)Cadence工作流的吞吐量非常有限,而工作流的數(shù)量實(shí)際上是無限的。因此,如果您需要聚合每個(gè)客戶的事件,并且您的應(yīng)用程序有1億個(gè)客戶,并且每個(gè)客戶每秒生成的事件不超過20個(gè),那么Cadence就可以正常工作了。但是,如果您想為美國客戶聚合所有事件,那么這些事件的發(fā)生率將超出單個(gè)工作流的容量。
例如,物聯(lián)網(wǎng)設(shè)備生成事件,某個(gè)事件序列指示應(yīng)重新配置該設(shè)備。將為每個(gè)設(shè)備創(chuàng)建一個(gè)工作流實(shí)例,每個(gè)實(shí)例將管理設(shè)備的狀態(tài)機(jī),并在必要時(shí)執(zhí)行重新配置活動(dòng)。
另一個(gè)用例是客戶忠誠度計(jì)劃。每次客戶進(jìn)行購買時(shí),都會(huì)在apachekafka中生成一個(gè)事件供下游系統(tǒng)處理。忠誠度服務(wù)Kafka消費(fèi)者接收事件并使用Cadence signalWorkflowExecution API向客戶發(fā)送有關(guān)購買的工作流。工作流將累積購買的計(jì)數(shù)。如果達(dá)到指定的閾值,工作流將執(zhí)行一個(gè)活動(dòng),通知某些外部服務(wù)客戶已達(dá)到下一級(jí)忠誠度計(jì)劃。工作流還執(zhí)行活動(dòng),定期向客戶發(fā)送有關(guān)其當(dāng)前狀態(tài)的消息。
3.3.2、人工任務(wù)(Human Tasks)
許多業(yè)務(wù)流程都涉及到人工參與者。實(shí)現(xiàn)外部交互的標(biāo)準(zhǔn)節(jié)奏模式是執(zhí)行在外部系統(tǒng)中創(chuàng)建人工任務(wù)的活動(dòng)。它可以是帶有表單的電子郵件,或者外部數(shù)據(jù)庫中的記錄,或者移動(dòng)應(yīng)用程序通知。當(dāng)用戶更改任務(wù)的狀態(tài)時(shí),會(huì)向相應(yīng)的工作流發(fā)送一個(gè)信號(hào)。例如,在提交表單或確認(rèn)移動(dòng)應(yīng)用程序通知時(shí)。有些任務(wù)有多個(gè)可能的操作,如索賠、退貨、完成、拒絕。因此可以發(fā)送與之相關(guān)的多個(gè)信號(hào)。
3.3.3、過程執(zhí)行變更(Process Execution Alteration)
如果發(fā)生了一些外部事件,一些業(yè)務(wù)流程應(yīng)該改變它們的行為。例如,在執(zhí)行訂單裝運(yùn)工作流時(shí),項(xiàng)目數(shù)量的任何更改都可以以信號(hào)的形式傳遞。
另一個(gè)例子是服務(wù)部署工作流。當(dāng)向Kubernetes集群推出新的軟件版本時(shí),發(fā)現(xiàn)了一些問題。在調(diào)查問題時(shí),可以使用一個(gè)信號(hào)來請(qǐng)求工作流暫停。然后,可以使用continue或rollback信號(hào)來執(zhí)行適當(dāng)?shù)牟僮鳌?/p>
3.3.4、異步處理(Synchronization)
Cadence工作流非常一致,因此可以將它們用作執(zhí)行操作的同步點(diǎn)。例如,需要按順序處理單個(gè)用戶的所有消息,但底層消息傳遞基礎(chǔ)結(jié)構(gòu)可以并行地傳遞它們。Cadence的解決方案是為每個(gè)用戶提供一個(gè)工作流,并在收到事件時(shí)向其發(fā)出信號(hào)。然后,工作流將緩沖內(nèi)部數(shù)據(jù)結(jié)構(gòu)中的所有信號(hào),然后為接收到的每個(gè)信號(hào)調(diào)用一個(gè)活動(dòng)。
3.4、異常查詢(Synchronous query)
工作流代碼是有狀態(tài)的,Cadence框架在各種軟件和硬件故障時(shí)保持它。在工作流執(zhí)行期間,狀態(tài)會(huì)不斷變化。為了向外部世界公開這種內(nèi)部狀態(tài),Cadence提供了一個(gè)同步查詢特性。從工作流實(shí)現(xiàn)者的角度來看,查詢公開為外部實(shí)體調(diào)用的同步回調(diào)。每個(gè)工作流類型可以提供多個(gè)這樣的回調(diào),向不同的外部系統(tǒng)公開不同的信息。
要執(zhí)行查詢,外部客戶機(jī)調(diào)用同步Cadence API,提供域、工作流ID、查詢名稱和可選的查詢參數(shù)。
查詢回調(diào)必須是只讀的,不能以任何方式更改工作流狀態(tài)。另一個(gè)限制是查詢回調(diào)不能包含任何阻塞代碼。以上兩個(gè)限制都排除了從查詢處理程序調(diào)用活動(dòng)的能力。
Cadence團(tuán)隊(duì)目前正致力于實(shí)現(xiàn)更新特性,該特性在調(diào)用方式上類似于查詢,但將支持工作流狀態(tài)變異和本地活動(dòng)調(diào)用。
3.4.1、堆棧跟蹤查詢(Stack Trace Query)
Cadence客戶機(jī)庫公開了一些現(xiàn)成的預(yù)定義查詢。目前唯一支持的內(nèi)置查詢是stack_trace。此查詢返回所有工作流擁有的線程的堆棧。這是解決生產(chǎn)中任何工作流問題的好方法。
3.5、任務(wù)列表(Task Lists)
當(dāng)工作流調(diào)用活動(dòng)時(shí),它將ScheduleActivityTask決策發(fā)送到Cadence服務(wù)。因此,服務(wù)更新工作流狀態(tài)并將活動(dòng)任務(wù)分派給實(shí)現(xiàn)該活動(dòng)的工作人員。使用中間隊(duì)列而不是直接調(diào)用工作進(jìn)程。因此,服務(wù)將向該隊(duì)列添加一個(gè)活動(dòng)任務(wù),工作線程將使用長輪詢請(qǐng)求接收該任務(wù)。Cadence將用于分派活動(dòng)任務(wù)的隊(duì)列稱為活動(dòng)任務(wù)列表。
類似地,當(dāng)工作流需要處理外部事件時(shí),將創(chuàng)建一個(gè)決策任務(wù)。決策任務(wù)列表用于將其傳遞給工作流工作人員(也稱為決策者)。
雖然Cadence任務(wù)列表是隊(duì)列,但它們與常用的隊(duì)列技術(shù)有一些不同。主要的一點(diǎn)是,它們不需要顯式注冊(cè),而是按需創(chuàng)建的。任務(wù)列表的數(shù)量不受限制。一個(gè)常見的用例是為每個(gè)工作進(jìn)程提供一個(gè)任務(wù)列表,并使用它向流程交付活動(dòng)任務(wù)。另一個(gè)用例是每個(gè)工人池都有一個(gè)任務(wù)列表。
使用任務(wù)列表傳遞任務(wù)而不是通過同步RPC調(diào)用活動(dòng)工作線程有多種優(yōu)勢(shì):
-
工人不需要有任何開放的端口,這是更安全的。
-
Worker不需要通過DNS或任何其他網(wǎng)絡(luò)發(fā)現(xiàn)機(jī)制來公布自己。
-
當(dāng)所有工作線程都關(guān)閉時(shí),消息將保存在任務(wù)列表中,等待工作進(jìn)程恢復(fù)。
-
只有當(dāng)消息有空閑容量時(shí),工作線程才會(huì)輪詢消息,因此消息不會(huì)過載。
-
跨大量工作人員進(jìn)行自動(dòng)負(fù)載平衡。
-
任務(wù)列表支持服務(wù)器端限制。這允許您將任務(wù)分派率限制為工作人員池,并且在峰值發(fā)生時(shí)仍然支持以更高的速率添加任務(wù)。
-
任務(wù)列表可用于將請(qǐng)求路由到特定的工作人員池,甚至是特定的進(jìn)程。
3.6、跨DC復(fù)制(Cross-DC replication)
Cadence全局域功能為客戶端提供了在發(fā)生數(shù)據(jù)中心故障轉(zhuǎn)移時(shí)從另一個(gè)群集繼續(xù)執(zhí)行工作流的能力。盡管可以將全局域配置為復(fù)制到任意數(shù)量的群集,但它僅在單個(gè)群集中被視為活動(dòng)域。
3.6.1、全局域體系結(jié)構(gòu)(Global Domains Architecture)
Cadence引入了一個(gè)新的頂級(jí)實(shí)體Global Domains,它支持跨集群復(fù)制工作流執(zhí)行。客戶機(jī)應(yīng)用程序需要運(yùn)行工人輪詢所有集群上的活動(dòng)/決策任務(wù)。Cadence將只在當(dāng)前活動(dòng)集群上分派任務(wù);備用集群上的工作線程將處于空閑狀態(tài),直到全局域發(fā)生故障轉(zhuǎn)移。
因?yàn)镃adence是一個(gè)提供高度一致語義的服務(wù),所以我們只允許在活動(dòng)集群上發(fā)生StartWorkflowExecution、SignalWorkflowExecution等外部事件。全局域依賴于本地群集(local_Quorum)上的輕量級(jí)事務(wù)(paxos)來更新工作流執(zhí)行狀態(tài),并創(chuàng)建異步應(yīng)用的復(fù)制任務(wù),以跨群集復(fù)制狀態(tài)。如果應(yīng)用程序在全局域處于待機(jī)模式的群集上進(jìn)行這些API調(diào)用,Cadence將使用包含當(dāng)前活動(dòng)群集名稱的DomainNotActivieError拒絕這些調(diào)用。應(yīng)用程序負(fù)責(zé)將外部事件轉(zhuǎn)發(fā)到當(dāng)前處于活動(dòng)狀態(tài)的群集。
3.6.2、全局域的新配置(New config for Global Domains)
3.6.2.1、全局(IsGlobal)
此配置用于區(qū)分集群本地域和全局域。它控制在更新時(shí)創(chuàng)建復(fù)制任務(wù),允許在集群之間復(fù)制狀態(tài)。只有當(dāng)域設(shè)置為只讀時(shí)才可設(shè)置。
3.6.2.2、集群(Clusters)
域可以故障轉(zhuǎn)移到的群集列表,包括當(dāng)前活動(dòng)群集。這也是一個(gè)只讀設(shè)置,只能在設(shè)置域時(shí)設(shè)置。路線圖上的重新復(fù)制特性將允許在將來更新此配置以添加/刪除群集。
3.6.2.3、活動(dòng)集群名稱(Active Cluster Name)
全局域的當(dāng)前活動(dòng)群集的名稱。每次全局域故障轉(zhuǎn)移到另一個(gè)群集時(shí),都會(huì)更新此配置。
3.6.2.4、文件版本(Failover Version)
唯一的故障轉(zhuǎn)移版本,也表示全局域的當(dāng)前活動(dòng)群集。Cadence允許從任何集群觸發(fā)故障轉(zhuǎn)移,所以故障轉(zhuǎn)移版本的設(shè)計(jì)方式是在兩個(gè)集群上錯(cuò)誤地同時(shí)觸發(fā)故障轉(zhuǎn)移時(shí)不允許發(fā)生沖突。
3.6.3、沖突解決(Conflict Resolution)
與只為活動(dòng)執(zhí)行提供一次語義的局部域不同,全局域只能支持至少一次語義。Cadence XDC依賴于跨集群的異步事件復(fù)制,因此在發(fā)生故障轉(zhuǎn)移時(shí),由于復(fù)制任務(wù)延遲,活動(dòng)可能會(huì)在新的活動(dòng)集群上再次被調(diào)度。這也意味著,無論何時(shí)在新群集進(jìn)行故障轉(zhuǎn)移后更新工作流執(zhí)行,都無法應(yīng)用該執(zhí)行之前的任何復(fù)制任務(wù)。這會(huì)導(dǎo)致上一個(gè)活動(dòng)集群中工作流執(zhí)行所取得的某些進(jìn)展丟失。在這種沖突解決過程中,Cadence在放棄復(fù)制任務(wù)之前,會(huì)將任何外部事件(如信號(hào))重新注入到新的歷史中。即使在故障轉(zhuǎn)移期間某些進(jìn)度可能會(huì)回滾,但Cadence可以保證工作流不會(huì)卡住,并將繼續(xù)向前推進(jìn)。
3.6.4、可視化API(Visibility API)
在主集群和備用集群上都允許所有可見性api。這使得Cadence Web能夠無縫地為全局域工作,因?yàn)榭梢詮挠驈?fù)制到的任何集群中查詢工作流執(zhí)行的所有可見性記錄。即使全局域處于待機(jī)狀態(tài),直接調(diào)用Cadence可見性API的應(yīng)用程序也將繼續(xù)工作。但是,在從備用集群查詢工作流執(zhí)行狀態(tài)時(shí),由于復(fù)制延遲,它們可能會(huì)看到延遲。
3.6.5、CLI
Cadence CLI還可用于查詢域配置或執(zhí)行故障轉(zhuǎn)移。
總結(jié)
以上是生活随笔為你收集整理的微服务编排引擎Cadence简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 固态硬盘测试
- 下一篇: 量子物理 詹班 计算机,西南交大 大学物