掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
譯者 | 李睿

審校 | 重樓
本文將分享一些在Mule4中創(chuàng)建高可靠應(yīng)用的優(yōu)秀實踐。而用戶對可靠性的期望是在Mule應(yīng)用程序停止或崩潰之后不會丟失消息或數(shù)據(jù)。
這里分享的大部分配置細節(jié)(與可靠性相關(guān))都來自MuleSoft文檔/文章。
當在單個運行時實例模式下運行Mule應(yīng)用程序時,持久隊列通過序列化并將內(nèi)容存儲在磁盤上來工作。但是,當在集群運行時實例模式下運行Mule應(yīng)用程序時,持久隊列會備份在內(nèi)存網(wǎng)格中。在單個運行時實例模式或集群運行時實例模式下,當使用持久隊列時,發(fā)送的數(shù)據(jù)必須是可序列化的。
CloudHub(1.0)部署的應(yīng)用程序可以選擇使用CloudHub持久隊列。CloudHub持久隊列是一種云服務(wù),允許將發(fā)布到虛擬機(VM)隊列的消息存儲在應(yīng)用程序的外部。
CloudHub持久隊列可以在每個應(yīng)用程序的基礎(chǔ)上啟用,該選項可以在運行時管理器→應(yīng)用程序→設(shè)置頁面中找到。如果用戶擁有這一權(quán)限,還可以選擇加密持久隊列以增加安全性。這一功能僅適用于擁有白金及以上訂閱權(quán)限的用戶。
Anypoint MQ是一個多租戶的云消息傳遞服務(wù),允許客戶在其應(yīng)用程序之間執(zhí)行高級異步消息傳遞方案。Anypoint MQ與Anypoint平臺完全集成,提供基于角色的訪問控制、客戶端管理和連接器。
Anypoint MQ確保安全可靠的消息傳遞。自動啟用跨多個數(shù)據(jù)中心的持久數(shù)據(jù)存儲,以確保消息隊列架構(gòu)能夠處理數(shù)據(jù)中心中斷并具有完全的災(zāi)難恢復。對消息隊列進行加密以確保數(shù)據(jù)處于靜止狀態(tài),或?qū)⑾l(fā)送到死信隊列以提高可靠性。
安裝和配置Anypoint MQ
在Anypoint Studio中,
用于JMS(Java消息服務(wù))的Anypoint連接器(JMS連接器)支持向?qū)崿F(xiàn)JMS規(guī)范的任何消息服務(wù)的隊列和主題發(fā)送和接收消息。
配置源:
可以配置以下三個輸入源中的一個來使用JMS連接器:
要配置“新建消息”源,執(zhí)行以下步驟:
在JMS配置窗口中,為“連接”選擇要提供給此配置的連接類型之一:
要為JMS連接器添加操作,遵循以下步驟:
對象存儲是一個存儲鍵值信息的存儲容器。對象存儲可以是持久的或暫時的(非持久的),在應(yīng)用程序重啟的情況下,持久性操作系統(tǒng)不會丟失任何信息(鍵值),而非持久性(鍵值)信息丟失。
使用默認對象存儲
在默認情況下,每個Mule應(yīng)用程序都有一個持久的對象存儲,并且總是可以在不需要任何配置的情況下對應(yīng)用程序可用。數(shù)據(jù)流可以使用它來持久化和共享數(shù)據(jù)。
如果希望使用默認的對象存儲,可以為對象存儲指定鍵,而無需為對象存儲操作選擇或創(chuàng)建對象存儲引用,也無需在對象存儲組件的XML元素中指定對象存儲屬性。
Mule應(yīng)用程序使用運行時管理器部署到CloudHub worker,但是默認對象存儲的內(nèi)容在應(yīng)用程序的應(yīng)用程序數(shù)據(jù)頁面的運行時管理器中是不可見的。
使用自定義對象存儲
自定義對象存儲必須指定對象存儲屬性。這些對象存儲可以配置為不同于默認對象存儲的行為。例如,可以指出對象存儲是持久的(這樣對象存儲的數(shù)據(jù)在Mule運行時崩潰時仍然存在)還是瞬態(tài)的(在Mule運行時崩潰時數(shù)據(jù)不存在)。
Anypoint Runtime Fabric提供Persistence Gateway。
允許部署到Mule運行時實例的Mule應(yīng)用程序在應(yīng)用程序副本和重啟之間存儲和共享數(shù)據(jù),從而確保可靠性。
在Anypoint Runtime Fabric中配置了Persistence Gateway后,它就可以用于部署到Mule運行時引擎(4.2.1或更高版本)的Mule應(yīng)用程序。在配置完成后,用戶可以在使用運行時管理器部署應(yīng)用程序時選擇“使用持久對象存儲”。
Mule應(yīng)用程序通過對象存儲連接器使用對象存儲v2 REST API連接到Persistence Gateway。這使得用戶可以同時部署到Anypoint Runtime Fabric和CloudHub,而無需修改Mule應(yīng)用程序。
在配置過程中,Persistence Gateway創(chuàng)建所需的數(shù)據(jù)庫模式。然后,當部署到Runtime Fabric的應(yīng)用程序被配置為使用持久對象存儲時,Persistence Gateway將必要的行寫入數(shù)據(jù)庫。
要配置Persistence Gateway,必須創(chuàng)建一個Kubernetes自定義資源,該資源允許集群連接到持久性數(shù)據(jù)存儲。
Create a Kubernetes Secret
Shell
kubectl create secret generic -n rtf --from-literal=persistence-gateway-creds='postgres://
es://username:pass@host:port/databasename' 為數(shù)據(jù)存儲創(chuàng)建自定義資源
1.將自定義資源模板從Kubernetes自定義資源模板復制到一個名為custom-resource.yaml的文件中。
2.確保secretRef:name的值與Kubernetes秘密文件中定義的name字段匹配。
3.根據(jù)環(huán)境的需要修改自定義資源模板的其他字段。
4.運行kubectl apply-f customientresource.yaml。
檢查Persistence Gateway Pod的日志,以確保它可以與數(shù)據(jù)庫通信
Shell
kubectl get pods -n rtf
尋找具有名稱前綴Persistence Gateway Pod
Shell
kubectl logs -f persistence-gateway-6dfb98949c-7xns9 -nrtf
參考上面的“異步處理”。
另一種選擇是將數(shù)據(jù)持久化在外部存儲系統(tǒng)中,如DB、FTP、外部緩存等。Mule應(yīng)用程序可以使用連接器連接到這些系統(tǒng)。
不同的外部存儲提供不同的服務(wù)質(zhì)量(QoS)級別,從而確??煽啃裕?
當Mule應(yīng)用程序中的操作無法連接到外部服務(wù)器時,默認行為是操作立即失敗并返回連接錯誤。
為了確保不丟失數(shù)據(jù),可以通過為該操作配置重連接策略來修改這一默認行為。
可以通過修改操作屬性或修改操作的全局元素的配置來配置操作的重連接策略。
連接性測試在Mule應(yīng)用程序啟動時運行,然后在應(yīng)用程序運行時定期運行。重新連接策略指示當連接失敗時應(yīng)該做什么。
以下是可用的重連接策略及其行為:
XML示例代碼:
XML
XML
在默認情況下,只會記錄一個失敗的連接測試,Mule應(yīng)用程序無論如何都會啟動或繼續(xù)運行而不嘗試重新連接。但是,可以在某些連接器操作上配置重新連接策略,以代替重復嘗試連接。
配置屬性/參數(shù)如下:
< reconnection >的屬性
failsDeployment:如果為true,當測試連接失敗時導致部署失敗。默認為false。
Blocking:如果為false,重連接策略在一個單獨的非阻塞線程中運行。默認為true。
Frequency:重新連接的頻率(毫秒)。默認為2000。
Count:嘗試重連的次數(shù)。默認值為2。
Blocking:如果為false,重連接策略在一個單獨的非阻塞線程中運行。默認為true。
Frequency:指定重新連接的頻率(單位:毫秒)。默認為2000。
重新傳遞策略(Redelivery Policy)是一個過濾器,通過限制Mule運行時引擎(Mule)執(zhí)行產(chǎn)生錯誤的消息的次數(shù)來幫助節(jié)省資源。
當向流的源添加重新傳遞策略時,Mule會在執(zhí)行流的組件之前評估接收到的數(shù)據(jù)。如果消息傳遞失敗了指定次數(shù),則重新傳遞策略將阻止流處理接收到的數(shù)據(jù),并引發(fā)REDELIVERY_EXHAUSTED錯誤。
在流中的事件源上配置重新發(fā)送策略,例如:HTTPListener;關(guān)于新建或更新的文件;在JMS連接器的新消息等上指定編號。在引發(fā)REDELIVERY_EXHAUSTED錯誤之前,流可以處理由事件源發(fā)出的“相同”事件的次數(shù)。
以下是配置參數(shù):
每次源接收到一個新消息,Mule通過生成它的密鑰來識別該消息。
Mule4引入了可重復流作為處理流的默認框架。可重復流使用戶能夠:
該策略最初使用的內(nèi)存緩沖區(qū)大小為512KB。對于較大的流,該策略在磁盤上創(chuàng)建一個臨時文件來存儲內(nèi)容,而不會溢出內(nèi)存。
如果需要處理大文件或小文件,可以改變緩沖區(qū)大小(inMemorySize)來優(yōu)化性能:
還可以設(shè)置緩沖區(qū)的度量單位(bufferUnit)。
XML示例代碼:
XML
事務(wù)是Mule應(yīng)用程序中的操作,其結(jié)果需要保持確定。當流中的一系列步驟必須作為一個單元成功或失敗時,Mule使用事務(wù)來劃分該單元。
Mule支持單一資源(默認為本地)和擴展架構(gòu)(XA)事務(wù)類型(transactionType)。唯一可以定義事務(wù)類型的組件是消息源(例如jms:listener和vm:listener)和Try scope。
單一資源事務(wù)(也稱為簡單事務(wù)或本地事務(wù))僅使用單一資源發(fā)送或接收消息:JMS代理、VM隊列或JDBC連接。
XML示例代碼:
XML
Mule只提交成功通過完整流的消息。如果在流中的任何一點上,消息拋出了一個傳播的錯誤(不是由出錯時繼續(xù)處理的),Mule將回滾事務(wù)。
擴展架構(gòu)事務(wù)(或XA事務(wù))可用于將來自多個事務(wù)資源(如VM、JMS或Database)的一系列操作分組到單個可靠的全局事務(wù)中。
XA(擴展架構(gòu))標準是一個X/Open組標準,它指定了全局事務(wù)管理器和本地事務(wù)資源管理器之間的接口。XA協(xié)議定義了一個兩階段提交協(xié)議,可用于跨不同類型的多個服務(wù)器可靠地協(xié)調(diào)和排序一系列原子操作。每個本地XA資源管理器都支持A.C.I.D屬性(原子性、一致性、隔離性和持久性),這些屬性有助于確保XA資源管理器管理的資源中操作序列的完成。
XML示例代碼:
XML
${insertQuery}
如果db:insert操作失敗,事務(wù)將在錯誤處理程序(on-error-propagate)執(zhí)行之前回滾(即它不是由on-error-continue處理的)。因此,通過vm:publish發(fā)送的消息不會被確認發(fā)送,而jms:consume中的消息也不會被實際使用,因此下次可以再次使用它。
下表描述了每種事務(wù)類型的特征以及加入事務(wù)的操作所需的條件:
Mule4中支持事務(wù)的常見連接器操作:
事務(wù)操作(transactionalAction)定義了操作對事務(wù)采取的操作類型。
下表描述了所有可用的事務(wù)操作:
在消息源中,可以從消息源啟動事務(wù)。在這種情況下,整個流成為一個事務(wù)。
要從消息源發(fā)起事務(wù),請配置其事務(wù)類型和事務(wù)操作:
XML
Mule流也能夠以非事務(wù)性連接器(如HTTP)開始,它需要流中的事務(wù)。在這種情況下,可以使用Try scope來設(shè)置事務(wù)。
可以在Try scope組件中通過設(shè)置事務(wù)類型和事務(wù)操作來設(shè)置事務(wù):
?在Anypoint Studio中:打開Try scope的General選項卡,設(shè)置事務(wù)類型和事務(wù)操作值:
?在配置XML中:添加transactionaction元素和transactionType元素(如果需要的話),并設(shè)置它們的值:
XML
INSERT INTO main_flow_audit (errorType, description) VALUES (:errorType, :description)
Bitronix是Mule應(yīng)用程序的XA事務(wù)管理器。Bitronix事務(wù)管理器允許Mule在重啟時自動恢復中斷的事務(wù)。
要使用Bitronix(在單個應(yīng)用程序中或在Mule域中的所有應(yīng)用程序中),在Mule應(yīng)用程序中將其聲明為全局配置元素:
XML
...
可以添加Bitronix
從Studio導入到應(yīng)用程序或域,執(zhí)行以下步驟:
下表列出了Bitronix的配置屬性:
批處理作業(yè)組件設(shè)計用于對大于內(nèi)存的數(shù)據(jù)集進行可靠的異步處理。它自動拆分源數(shù)據(jù),并將其存儲到持久隊列中,從而可以處理大型數(shù)據(jù)集。
該組件可配置如下:
Until Successful作用域依次執(zhí)行其中的處理器,直到所有處理器都成功,或者該作用域耗盡了最大重試次數(shù)。Until Successful同步運行。如果作用域內(nèi)的任何處理器未能連接或未能產(chǎn)生成功的結(jié)果,則Until Successful將重試其中的所有處理器,包括失敗的處理器,直到所有配置的重試都耗盡。如果重試成功,作用域?qū)⒗^續(xù)到下一個組件。如果最后一次重試不成功,Until Successful將報錯。
要配置Until Successful作用域,需要在應(yīng)用程序流中添加
可以在Until Successful作用域內(nèi)配置以下屬性:
XML示例代碼:
XML
上面的XML示例配置了由調(diào)度器組件和執(zhí)行FTP寫入操作的Until Successful作用域觸發(fā)的流。
First Successful路由器遍歷已配置的處理路由列表,直到其中一條路由成功執(zhí)行。如果任何處理路由執(zhí)行失敗(拋出錯誤),路由器執(zhí)行下一個配置的路由。如果配置的路由都沒有成功執(zhí)行,F(xiàn)irst Successful路由將拋出一個錯誤。
First Successful路由器在成功執(zhí)行路由后停止執(zhí)行。
XML示例代碼:
XML
可靠性模式是一種為應(yīng)用程序提供可靠消息傳遞的設(shè)計,即使應(yīng)用程序從非事務(wù)性連接器接收消息??煽啃阅J綄⒖煽康墨@取流與應(yīng)用程序邏輯流耦合在一起。
可靠獲取流(圖的左側(cè))可靠地將消息從沒有實現(xiàn)事務(wù)的消息源傳遞到實現(xiàn)事務(wù)的連接器的出站操作。操作可以是任何類型的事務(wù)端點,比如VM或JMS。如果可靠獲取流不能傳遞消息,它將確保消息不會丟失。
應(yīng)用程序邏輯流(圖的右側(cè))將使用事務(wù)連接器的消息源中的消息傳遞到應(yīng)用程序的業(yè)務(wù)邏輯。
XML示例代碼:
XML
(1)
(2)
在實現(xiàn)可靠性模式時,需要考慮以下幾點:
可靠性測試是一項重要的軟件測試技術(shù),由團隊執(zhí)行,以確保軟件在每種環(huán)境條件下以及在指定的時間內(nèi)始終如一地執(zhí)行和運行。
該測試包含了功能測試和非功能測試的結(jié)果,例如壓力測試、安全測試、功能測試、生產(chǎn)測試等。
JSON模塊驗證可用于根據(jù)JSON模式驗證JSON。它將顯示JSON有效負載的確切錯誤,因此可以將傳入的JSON錯誤通知客戶端。
類似地,有XML模塊驗證來根據(jù)XML模式驗證XML。
因為有適當?shù)尿炞C,這些模塊可以防止在流中進一步拋出錯誤,從而節(jié)省了確??煽啃缘念~外工作,例如持久化到DB、推入到DLQ等。
應(yīng)該正確處理上述任何實踐拋出的錯誤,以確保沒有數(shù)據(jù)丟失。
當引發(fā)錯誤的執(zhí)行次數(shù)大于配置的maxRedeliveryCount值時,從配置Redelivery策略的任何地方拋出。
在這種情況下,在“On Error Continue”作用域上,確保將消息(正在處理的當前消息)傳送/持久化到死信隊列(DLQ)中,這樣它就不會丟失。一旦持久化到DLQ中,任何類型的通知都可以發(fā)送到相關(guān)團隊。
XML示例代碼:
XML
當某個執(zhí)行塊的重試已經(jīng)耗盡時,從給定操作或從Until Successful作用域拋出。
在這種情況下,在“On Error Continue”作用域內(nèi),確保將消息(當前消息正在處理中)推送/持久化到死信隊列(DLQ)中,以使其不會丟失。一旦持久化到DLQ中,就可以向相關(guān)團隊發(fā)送通知失敗的任何類型的通知。
XML示例代碼:
XML
當事務(wù)期間發(fā)生錯誤時,應(yīng)用程序必須處理錯誤并繼續(xù)執(zhí)行或執(zhí)行回滾。
On Error Propagate
On Error Continue錯誤得到處理,事務(wù)保持活動狀態(tài)并能夠提交。on-error-continue中的處理器在事務(wù)中運行。
在上述任何一種情況下,確保將當前消息推入DLQ或DB等存儲系統(tǒng)。
Mule有三個選項來處理記錄級別的錯誤:
1.Finish processing停止當前作業(yè)實例的執(zhí)行。完成當前正在執(zhí)行的記錄的執(zhí)行,但不要從隊列中提取更多記錄,并將作業(yè)實例設(shè)置為FAILURE狀態(tài)。調(diào)用OnComplete階段。
2.繼續(xù)處理批處理,不考慮任何失敗的記錄,使用acceptExpression和acceptPolicy屬性指導后續(xù)批處理步驟如何處理失敗的記錄。
3.繼續(xù)處理批處理,不考慮任何失敗的記錄(使用acceptExpression和acceptPolicy屬性指示后續(xù)批處理步驟如何處理失敗的記錄),直到批處理作業(yè)積累了失敗記錄的最大數(shù)量,此時執(zhí)行將停止,就像選項1中那樣。
在最后兩種情況下,在ONLY_FAILURES批處理步驟中,將失敗的記錄推入DLQ或DB之類的存儲系統(tǒng)。
當配置的路由都沒有成功執(zhí)行時,通過將消息推入DLQ或DB之類的存儲系統(tǒng)來處理拋出的錯誤。
這是在一個地方整理各種可靠性問題的解決方案的努力,熱衷于構(gòu)建高可靠性應(yīng)用程序的Mule開發(fā)人員可以參考一些詳盡的列表。
需要記住的是,其中一些解決方案/實踐的性能可能會受到影響,因此在選擇時需要謹慎。
原文標題:Best Practices for Creating Highly Reliable Applications in Mule 4,作者:Praveen Sundar

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流