鍍金池/ 教程/ 大數(shù)據(jù)/ 調(diào)度程序代理管理者模式
索引表模式
Sharding 分片模式
外部配置存儲(chǔ)模式
命令和查詢職責(zé)分離(CQRS)模式
靜態(tài)內(nèi)容托管模式
運(yùn)行重構(gòu)模式
計(jì)算資源整合模式
Throttling 節(jié)流模式
斷路器模式
事件獲取模式
實(shí)體化視圖模式
緩存預(yù)留模式
守門員模式
聯(lián)合身份模式
補(bǔ)償交易模式
重試模式
領(lǐng)導(dǎo)人選舉模式
優(yōu)先級(jí)隊(duì)列模式
健康端點(diǎn)監(jiān)控模式
消費(fèi)者的競(jìng)爭(zhēng)模式
基于隊(duì)列的負(fù)載均衡模式
仆人鍵模式
管道和過濾器模式
調(diào)度程序代理管理者模式

調(diào)度程序代理管理者模式

協(xié)調(diào)一系列在分布式服務(wù)集和其他遠(yuǎn)程資源的的行為,試圖透明地處理故障,如果這些操作失敗,或撤銷,如果系統(tǒng)不能從故障中恢復(fù)執(zhí)行工作的影響。這種模式可以分布式系統(tǒng)中增加彈性和靈活性,使之恢復(fù)和重試失敗是由于短暫的異常,持久的故障和處理故障等操作。

背景和問題

應(yīng)用程序執(zhí)行其包括多個(gè)步驟,其中的一些可以調(diào)用遠(yuǎn)程服務(wù)或訪問遠(yuǎn)程資源的任務(wù)。各個(gè)步驟可以是相互獨(dú)立的,但它們是由實(shí)現(xiàn)該任務(wù)的應(yīng)用程序邏輯編排。

只要有可能,應(yīng)用程序應(yīng)該確保任務(wù)運(yùn)行完成和解決遠(yuǎn)程訪問服務(wù)或資源時(shí)可能發(fā)生的任何故障??赡軙?huì)因各種原因,這些故障。例如,該網(wǎng)絡(luò)可能是崩潰,通信可能被中斷,遠(yuǎn)程服務(wù)可能停止響應(yīng)或處于不穩(wěn)定的狀態(tài),或遠(yuǎn)程資源可能暫時(shí)無(wú)法訪問,可能由于資源約束。在許多情況下,這些故障可能是暫時(shí)的,并且可以通過使用重試模式進(jìn)行處理。

如果該應(yīng)用程序檢測(cè)到一個(gè)更永久的故障,從它可以不容易恢復(fù),它必須能夠?qū)⑾到y(tǒng)恢復(fù)到一致狀態(tài),并確保整個(gè)端至端的操作的完整性。

解決方案

調(diào)度代理管理者模式定義了以下角色。這些演員編排的步驟(工作,單個(gè)項(xiàng)目)將作為任務(wù)(整個(gè)過程)的一部分進(jìn)行:

  • 調(diào)度安排構(gòu)成的整體任務(wù)要執(zhí)行,并配合它們的操作的各個(gè)步驟??砂凑障铝胁襟E組合成一個(gè)管道或工作流,并且所述調(diào)度器是負(fù)責(zé)確保在這個(gè)工作流程中的步驟,以適當(dāng)?shù)捻樞虮粓?zhí)行。作為各步驟中進(jìn)行(如“步驟還未開始”,“步運(yùn)行時(shí),”或“步驟完成”),并記錄有關(guān)該狀態(tài)的信息的調(diào)度器維護(hù)關(guān)于工作流的狀態(tài)信息。這個(gè)狀態(tài)信息也應(yīng)包括的允許的步驟來完成(稱為完全按時(shí)間)的時(shí)間的上限。如果一個(gè)步驟需要訪問遠(yuǎn)程服務(wù)或資源時(shí),調(diào)度程序調(diào)用適當(dāng)?shù)拇沓绦?,通過它的工作的細(xì)節(jié)將被執(zhí)行。調(diào)度通常采用異步請(qǐng)求/響應(yīng)消息與代理進(jìn)行通訊。這可以通過使用隊(duì)列來實(shí)現(xiàn),盡管也可以使用其它分布式消息傳遞技術(shù)來代替。

注意: 調(diào)度程序執(zhí)行類似的功能,以在流程管理模式的過程管理器。實(shí)際工作流程通常被定義并通過由該調(diào)度器所控制的工作流引擎來實(shí)現(xiàn)。這種方法分離了業(yè)務(wù)邏輯從調(diào)度的工作流程。

  • 代理包含邏輯,封裝調(diào)用一個(gè)遠(yuǎn)程服務(wù),或訪問由在一個(gè)任務(wù)的步驟中引用的遠(yuǎn)程資源。每個(gè)代理通常通過它可以調(diào)用單個(gè)服務(wù)或資源,實(shí)施相應(yīng)的錯(cuò)誤處理和重試邏輯(如有超時(shí)限制,稍后說明)。如果由調(diào)度程序所運(yùn)行的工作流中的步驟利用在不同步驟的若干服務(wù)和資源,每個(gè)步驟可能會(huì)引用不同代理(這是其中的模式的實(shí)現(xiàn)細(xì)節(jié))。
  • 監(jiān)監(jiān)視由調(diào)度正在執(zhí)行中的任務(wù)步驟的狀態(tài)。它運(yùn)行周期(頻率將系統(tǒng)專用),檢查的步驟,通過調(diào)度為保持狀態(tài)。如果檢測(cè)到任何已超時(shí)或失敗,它會(huì)安排相應(yīng)的代理來恢復(fù)步驟或執(zhí)行相應(yīng)的補(bǔ)救措施(這可能涉及修改步驟的狀態(tài))。注意,恢復(fù)或補(bǔ)救行動(dòng)通常由調(diào)度器和代理執(zhí)行。主管應(yīng)該簡(jiǎn)單地要求這些行動(dòng)來執(zhí)行。

調(diào)度程序,代理和管理者是邏輯組件和它們的物理實(shí)現(xiàn)取決于所使用的技術(shù)。例如,若干個(gè)邏輯代理可以被實(shí)現(xiàn)為一個(gè)單一的網(wǎng)絡(luò)服務(wù)的一部分。

調(diào)度器維護(hù)關(guān)于任務(wù)的進(jìn)度和持久的數(shù)據(jù)存儲(chǔ)中的每個(gè)步驟中,被稱為狀態(tài)存儲(chǔ)的狀態(tài)信息。主管可以使用此信息來幫助確定一個(gè)步驟是否出現(xiàn)故障。圖1說明了調(diào)度程序的代理,監(jiān)事和狀態(tài)存儲(chǔ)之間的關(guān)系。

http://wiki.jikexueyuan.com/project/cloud-design-patterns/images/samm.png" alt="" />

圖1 - 在調(diào)度程序代理管理者模式的演員

注意:

此圖顯示的模式的簡(jiǎn)化圖。在實(shí)際的實(shí)現(xiàn)中,有可能是調(diào)度程序的多個(gè)實(shí)例同時(shí)運(yùn)行的任務(wù)的每個(gè)子集。類似地,系統(tǒng)可以運(yùn)行每個(gè)代理程序的多個(gè)實(shí)例,或者甚至多個(gè)監(jiān)控器。在這種情況下,主管必須協(xié)調(diào)其與對(duì)方認(rèn)真的工作,以確保它們不會(huì)爭(zhēng)來恢復(fù)同樣失敗的步驟和任務(wù)。在領(lǐng)導(dǎo)人選舉模式提供一個(gè)可能的解決了這個(gè)問題。

何時(shí)一個(gè)應(yīng)用程序希望執(zhí)行一個(gè)任務(wù),它提交一個(gè)請(qǐng)求給調(diào)度程序。調(diào)度記錄有關(guān)的任務(wù)及其步驟(例如,“步驟還未開始”)中的狀態(tài)存儲(chǔ)的初始狀態(tài)的信息,然后開始執(zhí)行由流程定義的操作。作為調(diào)度程序開始每一步時(shí),它將更新關(guān)于該步驟中的狀態(tài)存儲(chǔ)(例如,“步運(yùn)行的”)的狀態(tài)的信息。

如果一個(gè)步驟引用遠(yuǎn)程服務(wù)或資源時(shí),調(diào)度程序?qū)⑾l(fā)送給適當(dāng)代理。該消息可以包含代理需要傳遞給服務(wù)或訪問該資源,除了完整的通過時(shí)間的操作的信息。如果代理成功完成其操作時(shí),它返回到調(diào)度程序的響應(yīng)。然后調(diào)度程序可以更新在狀態(tài)存儲(chǔ)的狀態(tài)信息(例如,“步驟完成”),并進(jìn)行下一步驟。這個(gè)過程繼續(xù),直到整個(gè)任務(wù)完成。

代理可以實(shí)現(xiàn)任意重試邏輯需要執(zhí)行它的工作。但是,如果該代理之前,完成未完成其工作期間屆滿的調(diào)度程序就會(huì)認(rèn)為操作失敗。在這種情況下,代理應(yīng)該停止其工作,并沒有試圖東西返回到調(diào)度程序(甚至沒有錯(cuò)誤消息),或者進(jìn)行任何形式的恢復(fù)。這樣做的原因的限制是,后一步驟中已超時(shí)或失敗,則代理的另一個(gè)實(shí)例可被調(diào)度來運(yùn)行失敗的步驟(該過程將在后面描述)。

如果代理本身出現(xiàn)故障時(shí),調(diào)度程序?qū)⒉粫?huì)收到回復(fù)。該模式可能不會(huì)讓這一步驟已超時(shí),一個(gè)已經(jīng)失敗的真正區(qū)別。

如果一個(gè)步驟超時(shí)或失敗時(shí),狀態(tài)存儲(chǔ)將包含一個(gè)記錄,指出該步驟是否正在運(yùn)行(“步驟運(yùn)行”),但完全通過時(shí)間已經(jīng)過去了。監(jiān)事查找步驟,如本,并試圖恢復(fù)它們。一個(gè)可能的策略是為超級(jí)更新完成由值來擴(kuò)展可用來完成步驟的時(shí)間,然后將消息發(fā)送到調(diào)度器識(shí)別已超時(shí)的步驟。然后,調(diào)度程序可以嘗試重復(fù)此步驟。然而,這樣的設(shè)計(jì)要求為冪等的任務(wù)。

這可能是必需的管理者防止如果連續(xù)失敗或者超時(shí)被重試相同步驟。為了實(shí)現(xiàn)這一點(diǎn),對(duì)管理可維持一個(gè)重試計(jì)數(shù)為每一步,隨著狀態(tài)信息,在該狀態(tài)存儲(chǔ)。如果該計(jì)數(shù)超過預(yù)定閾值的管理者可以采用一種策略,例如,通知它應(yīng)重試步驟中,在期望的故障將在這段時(shí)間內(nèi)可以解決調(diào)度之前等待較長(zhǎng)的時(shí)間。或者,該管理者可以將消息發(fā)送到調(diào)度請(qǐng)求將整個(gè)任務(wù)通過實(shí)現(xiàn)補(bǔ)償交易被撤消(該方法將依賴于調(diào)度程序和代理提供所必需的信息,以實(shí)現(xiàn)對(duì)已成功完成各步驟的補(bǔ)償操作)。

注意:

這不是管理者的目的來監(jiān)控調(diào)度程序和代理商,如果他們不能重新啟動(dòng)它們。系統(tǒng)的這方面應(yīng)該由其中這些組件所運(yùn)行的基礎(chǔ)設(shè)施進(jìn)行處理。同樣,管理者不應(yīng)該是由調(diào)度所執(zhí)行的任務(wù)正在運(yùn)行(包括如何補(bǔ)償應(yīng)這些任務(wù)失敗)的實(shí)際業(yè)務(wù)運(yùn)作的知識(shí)。這是由調(diào)度程序執(zhí)行的工作流邏輯的目的。監(jiān)事的責(zé)任是確定的步驟是否已失敗,并安排要么為它重復(fù)或者包含失敗的步驟,整個(gè)任務(wù)被取消。

如果該調(diào)度程序是失敗的,或者工作流程后,重新啟動(dòng)正在由調(diào)度程序進(jìn)行意外終止,該調(diào)度程序應(yīng)能確定任何飛行任務(wù),這是處理失敗時(shí)的狀態(tài),并準(zhǔn)備繼續(xù)這個(gè)任務(wù)從該點(diǎn)上失敗了。該方法的實(shí)現(xiàn)細(xì)節(jié)都可能是特定的系統(tǒng)。如果任務(wù)不能恢復(fù),這可能是必要的,以撤消該任務(wù)已經(jīng)完成的工作。這可能還需要執(zhí)行一個(gè)補(bǔ)償事務(wù)。

這種模式的主要優(yōu)點(diǎn)是,該系統(tǒng)是彈性的意想不到的臨時(shí)或不可恢復(fù)故障的情況下。該系統(tǒng)可以構(gòu)造成可自愈。例如,如果一個(gè)代理程序或調(diào)度程序崩潰時(shí),一個(gè)新的可啟動(dòng)的,因而管理可以安排要恢復(fù)的任務(wù)。如果管理者發(fā)生故障,另一實(shí)例可以啟動(dòng),并且可以從發(fā)生故障的接管。如果管理者計(jì)劃定期運(yùn)行,一個(gè)新的實(shí)例可以被自動(dòng)預(yù)定義的時(shí)間間隔后啟動(dòng)。該狀態(tài)存儲(chǔ)可以被復(fù)制以實(shí)現(xiàn)更大程度的彈性。

問題和注意事項(xiàng)

在決定如何實(shí)現(xiàn)這個(gè)模式時(shí),您應(yīng)考慮以下幾點(diǎn):

  • 該圖案可以是平凡的執(zhí)行,并且需要的系統(tǒng)的每個(gè)可能的故障模式的全面測(cè)試。
  • 通過調(diào)度實(shí)現(xiàn)的恢復(fù)/重試邏輯可以是復(fù)雜的并且依賴于狀態(tài)存儲(chǔ)保持狀態(tài)信息。它也可能是必要的,記錄在一個(gè)持久的數(shù)據(jù)存儲(chǔ)區(qū)執(zhí)行一個(gè)補(bǔ)償事務(wù)處理所需的信息。
  • 與監(jiān)事運(yùn)行是非常重要的頻率。它應(yīng)該運(yùn)行足夠頻繁,以防止任何失敗堵塞長(zhǎng)時(shí)間的應(yīng)用程序的步驟,但它不應(yīng)該運(yùn)行非常頻繁,它成為一個(gè)開銷。
  • 由代理執(zhí)行的步驟可以被執(zhí)行一次以上。實(shí)現(xiàn)這些步驟的邏輯應(yīng)該是冪等。

何時(shí)使用這個(gè)模式

使用這種模式時(shí),在分布式環(huán)境中運(yùn)行,例如云的方法必須是有彈性的,以通信故障和/或運(yùn)行故障。

這種模式可能不適合任務(wù)不調(diào)用遠(yuǎn)程服務(wù)或訪問遠(yuǎn)程資源。

例子

實(shí)現(xiàn)一個(gè)電子商務(wù)系統(tǒng)中的 Web 應(yīng)用程序已經(jīng)部署在微軟的 Azure。用戶可以運(yùn)行此應(yīng)用程序來瀏覽提供一個(gè)組織的產(chǎn)品,下訂單,這些產(chǎn)品。用戶接口運(yùn)行作為一個(gè)網(wǎng)絡(luò)的作用,并且該應(yīng)用程序的命令處理元件被實(shí)現(xiàn)為一組工作角色。訂單處理邏輯的一部分包括訪問遠(yuǎn)程服務(wù),該系統(tǒng)的這一方面可能是易發(fā)生的瞬態(tài)或更持久的故障。為此,設(shè)計(jì)師使用了調(diào)度程序代理管理者模式實(shí)現(xiàn)了系統(tǒng)的訂單處理單元。

當(dāng)客戶下訂單時(shí),應(yīng)用程序構(gòu)建了一個(gè)消息,說明的順序和該職位的消息到隊(duì)列中。一個(gè)單獨(dú)的提交過程中,工人的角色運(yùn)行,檢索此消息,將訂單到訂單數(shù)據(jù)庫(kù)的詳細(xì)信息,并為在國(guó)家商店的訂單流程的記錄。請(qǐng)注意,插入到常規(guī)數(shù)據(jù)庫(kù)和國(guó)家存儲(chǔ)作為同一操作的一部分執(zhí)行。提交過程的設(shè)計(jì),以確保兩個(gè)刀片共同完成。

該提交進(jìn)程創(chuàng)建的訂單包括狀態(tài)信息:

  • 訂單ID:在訂單數(shù)據(jù)庫(kù)中的訂單的 ID。
  • LockedBy:的輔助角色的處理順序的實(shí)例 ID。有可能是運(yùn)行調(diào)度程序的工人角色的多個(gè)電流情況下,但每個(gè)訂單只能通過一個(gè)實(shí)例來處理。
  • CompleteBy:通過該命令應(yīng)處理的時(shí)間。
  • ProcessState:任務(wù)處理訂單的當(dāng)前狀態(tài)。可能的狀態(tài)是:
  • Pending:的順序已被創(chuàng)建,但處理尚未啟動(dòng)。
  • Processing:該命令正在處理中。
  • Processed:訂單已成功處理。
  • Error:訂單處理失敗。
  • FailureCount:次數(shù)的處理已經(jīng)嘗試了順序的號(hào)碼。

在這種狀態(tài)信息,OrderID 字段從新訂單的訂單 ID 復(fù)制。該 LockedBy 和 CompleteBy 字段設(shè)置為 null,則 ProcessState 字段設(shè)置為待定,并且 FailureCount 字段設(shè)置為 0。

注意:

在這個(gè)例子中,為了處理邏輯比較簡(jiǎn)單,只包括一個(gè)調(diào)用的遠(yuǎn)程服務(wù)的單個(gè)步驟。在一個(gè)更復(fù)雜的多步驟的情況下,提交過程很可能涉及多個(gè)步驟,所以多個(gè)記錄將在狀態(tài)存儲(chǔ),每一個(gè)描述了一個(gè)單獨(dú)的步驟中的狀態(tài)被創(chuàng)建。

該調(diào)度程序同時(shí)作為一個(gè)輔助角色的一部分,實(shí)現(xiàn)了處理訂單的業(yè)務(wù)邏輯。調(diào)度輪詢新訂單的一個(gè)實(shí)例探討了狀態(tài)存儲(chǔ)的記錄,其中 LockedBy 字段為空,并在 ProcessState 場(chǎng)待定。何時(shí)調(diào)度程序發(fā)現(xiàn)一個(gè)新的訂單,立刻填充LockedBy 字段與它自己的實(shí)例 ID,設(shè)置 CompleteBy 字段到一個(gè)適當(dāng)?shù)臅r(shí)間,并設(shè)置 ProcessState 字段來處理。執(zhí)行此代碼的設(shè)計(jì)是獨(dú)特和原子,以確保調(diào)度程序的兩個(gè)并發(fā)實(shí)例不能試圖同時(shí)處理的順序相同。

調(diào)度程序?qū)⑦\(yùn)行業(yè)務(wù)流程處理訂單異步,從狀態(tài)存儲(chǔ)傳遞給它的值在 OrderID 字段。工作流處理的順序檢索來自數(shù)據(jù)庫(kù)的訂單訂單的詳細(xì)信息,并執(zhí)行其工作。當(dāng)訂單處理流程的步驟需要調(diào)用遠(yuǎn)程服務(wù),它使用一個(gè)代理。在工作流步驟的代理通過利用對(duì)作為請(qǐng)求/響應(yīng)信道 Azure 的服務(wù)總線消息隊(duì)列進(jìn)行通信。圖2示出了該解決方案的一個(gè)高層視圖。

http://wiki.jikexueyuan.com/project/cloud-design-patterns/images/samm1.png" alt="" />

圖2 - 使用調(diào)度程序代理管理者模式在 Azure 的解決方案來處理訂單

從一個(gè)工作流步驟發(fā)送到代理的消息描述的順序,并包括 CompleteBy 時(shí)間。如果代理接收來自遠(yuǎn)程服務(wù)的響應(yīng)的 CompleteBy 時(shí)間到期之前,構(gòu)建其上的服務(wù)總線隊(duì)列在其上的工作流是聽張貼答復(fù)消息。當(dāng)工作流步驟接收到有效的應(yīng)答消息,它完成它的處理和調(diào)度臺(tái)的訂單狀態(tài) ProcessState 場(chǎng)處理。在這一點(diǎn)上,為了處理已成功完成。

如果 CompleteBy 時(shí)間到期的代理接收來自遠(yuǎn)程服務(wù)的響應(yīng)之前,代理簡(jiǎn)單地停止其處理,并終止處理順序。類似地,如果工作流處理的順序超過了 CompleteBy 時(shí),它也將終止。在這兩種情況下,在該狀態(tài)存儲(chǔ)在順序的狀態(tài)保持給定處理中,但 CompleteBy 時(shí)間指示的時(shí)間用于處理訂單已經(jīng)過去,該處理判定為不合格。請(qǐng)注意,如果正在訪問遠(yuǎn)程服務(wù),或者正在處理的順序工作流(或兩者)的代理意外終止,在狀態(tài)存儲(chǔ)的信息將再次保持設(shè)置為處理,最終將有過期 CompleteBy 值。

如果代理檢測(cè)到不可恢復(fù)的非瞬時(shí)性故障當(dāng)它正在嘗試聯(lián)系遠(yuǎn)程服務(wù),它可以發(fā)送一個(gè)錯(cuò)誤響應(yīng)返回到工作流。該調(diào)度程序可以設(shè)置為錯(cuò)誤,并提出了警示操作者的事件的狀態(tài)。然后,操作者可以嘗試手動(dòng)解決失敗的原因,并重新提交失敗的處理步驟。

主管定期檢查狀態(tài)存儲(chǔ)在尋找訂單,過期 CompleteBy 值。如果管理者發(fā)現(xiàn)這樣的記錄,它增加了 FailureCount 領(lǐng)域。如果 FailureCount 值低于規(guī)定的閾值時(shí),所述管理者復(fù)位 LockedBy 字段為空,更新 CompleteBy 場(chǎng)與新的到期時(shí)間,并設(shè)置 ProcessState 字段待定。調(diào)度程序的一個(gè)實(shí)例可以拿起這個(gè)命令并執(zhí)行其處理如前。如果 FailureCount 值超過特定閾值時(shí),對(duì)故障的原因被假定為非瞬態(tài)。監(jiān)事設(shè)置為錯(cuò)誤的狀態(tài),并引發(fā)了警報(bào)操作,如前所述的事件。

注意: 在這個(gè)例子中,管理者是在一個(gè)單獨(dú)的工作任務(wù)落實(shí)。您可以使用各種策略來安排監(jiān)理任務(wù)運(yùn)行,包括使用 Azure 的計(jì)劃程序服務(wù)(不要與計(jì)劃程序組件在此模式相混淆)。關(guān)于Azure的計(jì)劃程序服務(wù)的更多信息,請(qǐng)?jiān)L問調(diào)度程序頁(yè)面。

雖然未在本實(shí)施例中所示,該調(diào)度程序可能需要保留在通知關(guān)于單的進(jìn)度及狀態(tài)首位提交的順序應(yīng)用。應(yīng)用程序和調(diào)度程序彼此分離,以消除它們之間的任何相關(guān)性。該應(yīng)用程序并不知道哪個(gè)調(diào)度的實(shí)例處理的順序,調(diào)度不知道它的具體應(yīng)用實(shí)例發(fā)布的順序。

為使訂單狀態(tài)予以報(bào)道,該應(yīng)用程序可以使用自己的私人響應(yīng)隊(duì)列。這個(gè)響應(yīng)隊(duì)列的詳細(xì)信息將被納入送往提交過程的要求,其中包括在狀態(tài)存儲(chǔ)這些信息的一部分。該調(diào)度程序隨后將郵件投遞到該隊(duì)列表示訂單的狀態(tài)(“接收到的請(qǐng)求”,“為了完成”,“訂單失敗”,等等)。它應(yīng)包括訂單ID在這些消息中,以便它們可以與由該應(yīng)用程序的原始請(qǐng)求相關(guān)聯(lián)。