協(xié)調(diào)一系列在分布式服務(wù)集和其他遠(yuǎn)程資源的的行為,試圖透明地處理故障,如果這些操作失敗,或撤銷,如果系統(tǒng)不能從故障中恢復(fù)執(zhí)行工作的影響。這種模式可以分布式系統(tǒng)中增加彈性和靈活性,使之恢復(fù)和重試失敗是由于短暫的異常,持久的故障和處理故障等操作。
應(yīng)用程序執(zhí)行其包括多個步驟,其中的一些可以調(diào)用遠(yuǎn)程服務(wù)或訪問遠(yuǎn)程資源的任務(wù)。各個步驟可以是相互獨立的,但它們是由實現(xiàn)該任務(wù)的應(yīng)用程序邏輯編排。
只要有可能,應(yīng)用程序應(yīng)該確保任務(wù)運行完成和解決遠(yuǎn)程訪問服務(wù)或資源時可能發(fā)生的任何故障??赡軙蚋鞣N原因,這些故障。例如,該網(wǎng)絡(luò)可能是崩潰,通信可能被中斷,遠(yuǎn)程服務(wù)可能停止響應(yīng)或處于不穩(wěn)定的狀態(tài),或遠(yuǎn)程資源可能暫時無法訪問,可能由于資源約束。在許多情況下,這些故障可能是暫時的,并且可以通過使用重試模式進(jìn)行處理。
如果該應(yīng)用程序檢測到一個更永久的故障,從它可以不容易恢復(fù),它必須能夠?qū)⑾到y(tǒng)恢復(fù)到一致狀態(tài),并確保整個端至端的操作的完整性。
調(diào)度代理管理者模式定義了以下角色。這些演員編排的步驟(工作,單個項目)將作為任務(wù)(整個過程)的一部分進(jìn)行:
注意: 調(diào)度程序執(zhí)行類似的功能,以在流程管理模式的過程管理器。實際工作流程通常被定義并通過由該調(diào)度器所控制的工作流引擎來實現(xiàn)。這種方法分離了業(yè)務(wù)邏輯從調(diào)度的工作流程。
調(diào)度程序,代理和管理者是邏輯組件和它們的物理實現(xiàn)取決于所使用的技術(shù)。例如,若干個邏輯代理可以被實現(xiàn)為一個單一的網(wǎng)絡(luò)服務(wù)的一部分。
調(diào)度器維護(hù)關(guān)于任務(wù)的進(jìn)度和持久的數(shù)據(jù)存儲中的每個步驟中,被稱為狀態(tài)存儲的狀態(tài)信息。主管可以使用此信息來幫助確定一個步驟是否出現(xiàn)故障。圖1說明了調(diào)度程序的代理,監(jiān)事和狀態(tài)存儲之間的關(guān)系。
圖1 - 在調(diào)度程序代理管理者模式的演員
注意:
此圖顯示的模式的簡化圖。在實際的實現(xiàn)中,有可能是調(diào)度程序的多個實例同時運行的任務(wù)的每個子集。類似地,系統(tǒng)可以運行每個代理程序的多個實例,或者甚至多個監(jiān)控器。在這種情況下,主管必須協(xié)調(diào)其與對方認(rèn)真的工作,以確保它們不會爭來恢復(fù)同樣失敗的步驟和任務(wù)。在領(lǐng)導(dǎo)人選舉模式提供一個可能的解決了這個問題。
何時一個應(yīng)用程序希望執(zhí)行一個任務(wù),它提交一個請求給調(diào)度程序。調(diào)度記錄有關(guān)的任務(wù)及其步驟(例如,“步驟還未開始”)中的狀態(tài)存儲的初始狀態(tài)的信息,然后開始執(zhí)行由流程定義的操作。作為調(diào)度程序開始每一步時,它將更新關(guān)于該步驟中的狀態(tài)存儲(例如,“步運行的”)的狀態(tài)的信息。
如果一個步驟引用遠(yuǎn)程服務(wù)或資源時,調(diào)度程序?qū)⑾l(fā)送給適當(dāng)代理。該消息可以包含代理需要傳遞給服務(wù)或訪問該資源,除了完整的通過時間的操作的信息。如果代理成功完成其操作時,它返回到調(diào)度程序的響應(yīng)。然后調(diào)度程序可以更新在狀態(tài)存儲的狀態(tài)信息(例如,“步驟完成”),并進(jìn)行下一步驟。這個過程繼續(xù),直到整個任務(wù)完成。
代理可以實現(xiàn)任意重試邏輯需要執(zhí)行它的工作。但是,如果該代理之前,完成未完成其工作期間屆滿的調(diào)度程序就會認(rèn)為操作失敗。在這種情況下,代理應(yīng)該停止其工作,并沒有試圖東西返回到調(diào)度程序(甚至沒有錯誤消息),或者進(jìn)行任何形式的恢復(fù)。這樣做的原因的限制是,后一步驟中已超時或失敗,則代理的另一個實例可被調(diào)度來運行失敗的步驟(該過程將在后面描述)。
如果代理本身出現(xiàn)故障時,調(diào)度程序?qū)⒉粫盏交貜?fù)。該模式可能不會讓這一步驟已超時,一個已經(jīng)失敗的真正區(qū)別。
如果一個步驟超時或失敗時,狀態(tài)存儲將包含一個記錄,指出該步驟是否正在運行(“步驟運行”),但完全通過時間已經(jīng)過去了。監(jiān)事查找步驟,如本,并試圖恢復(fù)它們。一個可能的策略是為超級更新完成由值來擴(kuò)展可用來完成步驟的時間,然后將消息發(fā)送到調(diào)度器識別已超時的步驟。然后,調(diào)度程序可以嘗試重復(fù)此步驟。然而,這樣的設(shè)計要求為冪等的任務(wù)。
這可能是必需的管理者防止如果連續(xù)失敗或者超時被重試相同步驟。為了實現(xiàn)這一點,對管理可維持一個重試計數(shù)為每一步,隨著狀態(tài)信息,在該狀態(tài)存儲。如果該計數(shù)超過預(yù)定閾值的管理者可以采用一種策略,例如,通知它應(yīng)重試步驟中,在期望的故障將在這段時間內(nèi)可以解決調(diào)度之前等待較長的時間?;蛘?,該管理者可以將消息發(fā)送到調(diào)度請求將整個任務(wù)通過實現(xiàn)補(bǔ)償交易被撤消(該方法將依賴于調(diào)度程序和代理提供所必需的信息,以實現(xiàn)對已成功完成各步驟的補(bǔ)償操作)。
注意:
這不是管理者的目的來監(jiān)控調(diào)度程序和代理商,如果他們不能重新啟動它們。系統(tǒng)的這方面應(yīng)該由其中這些組件所運行的基礎(chǔ)設(shè)施進(jìn)行處理。同樣,管理者不應(yīng)該是由調(diào)度所執(zhí)行的任務(wù)正在運行(包括如何補(bǔ)償應(yīng)這些任務(wù)失敗)的實際業(yè)務(wù)運作的知識。這是由調(diào)度程序執(zhí)行的工作流邏輯的目的。監(jiān)事的責(zé)任是確定的步驟是否已失敗,并安排要么為它重復(fù)或者包含失敗的步驟,整個任務(wù)被取消。
如果該調(diào)度程序是失敗的,或者工作流程后,重新啟動正在由調(diào)度程序進(jìn)行意外終止,該調(diào)度程序應(yīng)能確定任何飛行任務(wù),這是處理失敗時的狀態(tài),并準(zhǔn)備繼續(xù)這個任務(wù)從該點上失敗了。該方法的實現(xiàn)細(xì)節(jié)都可能是特定的系統(tǒng)。如果任務(wù)不能恢復(fù),這可能是必要的,以撤消該任務(wù)已經(jīng)完成的工作。這可能還需要執(zhí)行一個補(bǔ)償事務(wù)。
這種模式的主要優(yōu)點是,該系統(tǒng)是彈性的意想不到的臨時或不可恢復(fù)故障的情況下。該系統(tǒng)可以構(gòu)造成可自愈。例如,如果一個代理程序或調(diào)度程序崩潰時,一個新的可啟動的,因而管理可以安排要恢復(fù)的任務(wù)。如果管理者發(fā)生故障,另一實例可以啟動,并且可以從發(fā)生故障的接管。如果管理者計劃定期運行,一個新的實例可以被自動預(yù)定義的時間間隔后啟動。該狀態(tài)存儲可以被復(fù)制以實現(xiàn)更大程度的彈性。
在決定如何實現(xiàn)這個模式時,您應(yīng)考慮以下幾點:
使用這種模式時,在分布式環(huán)境中運行,例如云的方法必須是有彈性的,以通信故障和/或運行故障。
這種模式可能不適合任務(wù)不調(diào)用遠(yuǎn)程服務(wù)或訪問遠(yuǎn)程資源。
實現(xiàn)一個電子商務(wù)系統(tǒng)中的 Web 應(yīng)用程序已經(jīng)部署在微軟的 Azure。用戶可以運行此應(yīng)用程序來瀏覽提供一個組織的產(chǎn)品,下訂單,這些產(chǎn)品。用戶接口運行作為一個網(wǎng)絡(luò)的作用,并且該應(yīng)用程序的命令處理元件被實現(xiàn)為一組工作角色。訂單處理邏輯的一部分包括訪問遠(yuǎn)程服務(wù),該系統(tǒng)的這一方面可能是易發(fā)生的瞬態(tài)或更持久的故障。為此,設(shè)計師使用了調(diào)度程序代理管理者模式實現(xiàn)了系統(tǒng)的訂單處理單元。
當(dāng)客戶下訂單時,應(yīng)用程序構(gòu)建了一個消息,說明的順序和該職位的消息到隊列中。一個單獨的提交過程中,工人的角色運行,檢索此消息,將訂單到訂單數(shù)據(jù)庫的詳細(xì)信息,并為在國家商店的訂單流程的記錄。請注意,插入到常規(guī)數(shù)據(jù)庫和國家存儲作為同一操作的一部分執(zhí)行。提交過程的設(shè)計,以確保兩個刀片共同完成。
該提交進(jìn)程創(chuàng)建的訂單包括狀態(tài)信息:
在這種狀態(tài)信息,OrderID 字段從新訂單的訂單 ID 復(fù)制。該 LockedBy 和 CompleteBy 字段設(shè)置為 null,則 ProcessState 字段設(shè)置為待定,并且 FailureCount 字段設(shè)置為 0。
注意:
在這個例子中,為了處理邏輯比較簡單,只包括一個調(diào)用的遠(yuǎn)程服務(wù)的單個步驟。在一個更復(fù)雜的多步驟的情況下,提交過程很可能涉及多個步驟,所以多個記錄將在狀態(tài)存儲,每一個描述了一個單獨的步驟中的狀態(tài)被創(chuàng)建。
該調(diào)度程序同時作為一個輔助角色的一部分,實現(xiàn)了處理訂單的業(yè)務(wù)邏輯。調(diào)度輪詢新訂單的一個實例探討了狀態(tài)存儲的記錄,其中 LockedBy 字段為空,并在 ProcessState 場待定。何時調(diào)度程序發(fā)現(xiàn)一個新的訂單,立刻填充LockedBy 字段與它自己的實例 ID,設(shè)置 CompleteBy 字段到一個適當(dāng)?shù)臅r間,并設(shè)置 ProcessState 字段來處理。執(zhí)行此代碼的設(shè)計是獨特和原子,以確保調(diào)度程序的兩個并發(fā)實例不能試圖同時處理的順序相同。
調(diào)度程序?qū)⑦\行業(yè)務(wù)流程處理訂單異步,從狀態(tài)存儲傳遞給它的值在 OrderID 字段。工作流處理的順序檢索來自數(shù)據(jù)庫的訂單訂單的詳細(xì)信息,并執(zhí)行其工作。當(dāng)訂單處理流程的步驟需要調(diào)用遠(yuǎn)程服務(wù),它使用一個代理。在工作流步驟的代理通過利用對作為請求/響應(yīng)信道 Azure 的服務(wù)總線消息隊列進(jìn)行通信。圖2示出了該解決方案的一個高層視圖。
圖2 - 使用調(diào)度程序代理管理者模式在 Azure 的解決方案來處理訂單
從一個工作流步驟發(fā)送到代理的消息描述的順序,并包括 CompleteBy 時間。如果代理接收來自遠(yuǎn)程服務(wù)的響應(yīng)的 CompleteBy 時間到期之前,構(gòu)建其上的服務(wù)總線隊列在其上的工作流是聽張貼答復(fù)消息。當(dāng)工作流步驟接收到有效的應(yīng)答消息,它完成它的處理和調(diào)度臺的訂單狀態(tài) ProcessState 場處理。在這一點上,為了處理已成功完成。
如果 CompleteBy 時間到期的代理接收來自遠(yuǎn)程服務(wù)的響應(yīng)之前,代理簡單地停止其處理,并終止處理順序。類似地,如果工作流處理的順序超過了 CompleteBy 時,它也將終止。在這兩種情況下,在該狀態(tài)存儲在順序的狀態(tài)保持給定處理中,但 CompleteBy 時間指示的時間用于處理訂單已經(jīng)過去,該處理判定為不合格。請注意,如果正在訪問遠(yuǎn)程服務(wù),或者正在處理的順序工作流(或兩者)的代理意外終止,在狀態(tài)存儲的信息將再次保持設(shè)置為處理,最終將有過期 CompleteBy 值。
如果代理檢測到不可恢復(fù)的非瞬時性故障當(dāng)它正在嘗試聯(lián)系遠(yuǎn)程服務(wù),它可以發(fā)送一個錯誤響應(yīng)返回到工作流。該調(diào)度程序可以設(shè)置為錯誤,并提出了警示操作者的事件的狀態(tài)。然后,操作者可以嘗試手動解決失敗的原因,并重新提交失敗的處理步驟。
主管定期檢查狀態(tài)存儲在尋找訂單,過期 CompleteBy 值。如果管理者發(fā)現(xiàn)這樣的記錄,它增加了 FailureCount 領(lǐng)域。如果 FailureCount 值低于規(guī)定的閾值時,所述管理者復(fù)位 LockedBy 字段為空,更新 CompleteBy 場與新的到期時間,并設(shè)置 ProcessState 字段待定。調(diào)度程序的一個實例可以拿起這個命令并執(zhí)行其處理如前。如果 FailureCount 值超過特定閾值時,對故障的原因被假定為非瞬態(tài)。監(jiān)事設(shè)置為錯誤的狀態(tài),并引發(fā)了警報操作,如前所述的事件。
注意:在這個例子中,管理者是在一個單獨的工作任務(wù)落實。您可以使用各種策略來安排監(jiān)理任務(wù)運行,包括使用 Azure 的計劃程序服務(wù)(不要與計劃程序組件在此模式相混淆)。關(guān)于Azure的計劃程序服務(wù)的更多信息,請訪問調(diào)度程序頁面。
雖然未在本實施例中所示,該調(diào)度程序可能需要保留在通知關(guān)于單的進(jìn)度及狀態(tài)首位提交的順序應(yīng)用。應(yīng)用程序和調(diào)度程序彼此分離,以消除它們之間的任何相關(guān)性。該應(yīng)用程序并不知道哪個調(diào)度的實例處理的順序,調(diào)度不知道它的具體應(yīng)用實例發(fā)布的順序。
為使訂單狀態(tài)予以報道,該應(yīng)用程序可以使用自己的私人響應(yīng)隊列。這個響應(yīng)隊列的詳細(xì)信息將被納入送往提交過程的要求,其中包括在狀態(tài)存儲這些信息的一部分。該調(diào)度程序隨后將郵件投遞到該隊列表示訂單的狀態(tài)(“接收到的請求”,“為了完成”,“訂單失敗”,等等)。它應(yīng)包括訂單ID在這些消息中,以便它們可以與由該應(yīng)用程序的原始請求相關(guān)聯(lián)。
更多建議: