批处理最佳做法
大多數(shù)應(yīng)用程序至少具有一個(gè)批處理任務(wù),在后臺執(zhí)行特定的邏輯。 編寫批處理作業(yè)并不復(fù)雜,但是您需要了解一些基本規(guī)則,我將列舉一些我發(fā)現(xiàn)最重要的規(guī)則。
從輸入類型的角度來看,處理項(xiàng)目可以通過輪詢處理項(xiàng)目存儲庫來實(shí)現(xiàn),也可以通過將它們通過隊(duì)列推送到系統(tǒng)中來實(shí)現(xiàn)。 下圖顯示了典型批處理系統(tǒng)的三個(gè)主要組件:
- 輸入組件(通過輪詢或從輸入隊(duì)列加載項(xiàng)目)
- 處理器:主要處理邏輯組件
- 輸出組件:輸出結(jié)果的輸出通道或存儲位置
1.始終分批輪詢
您一次只能檢索一批項(xiàng)目。 我最近不得不在嘗試檢索所有可能的項(xiàng)目進(jìn)行處理時(shí),診斷由計(jì)劃作業(yè)拋出的OutOfMemoryError。
系統(tǒng)集成測試正使用少量數(shù)據(jù),因此通過了,但是由于某些部署問題,當(dāng)計(jì)劃的作業(yè)脫機(jī)兩天時(shí),由于沒有人消耗它們,因此要處理的項(xiàng)目數(shù)已經(jīng)累積起來。 ,并且當(dāng)調(diào)度程序重新聯(lián)機(jī)時(shí),由于它們不適合調(diào)度程序的內(nèi)存堆,因此無法使用它們。 因此,僅設(shè)置高調(diào)度頻率速率是不夠的。
為了避免這種情況,您只需要獲取一批物料,將它們消耗掉即可,然后您可以重新運(yùn)行該過程,直到?jīng)]有剩余要處理的東西為止。
2.編寫線程安全的批處理程序
通常,無論您選擇并行運(yùn)行多少個(gè)作業(yè),計(jì)劃作業(yè)都應(yīng)正確運(yùn)行。 因此,批處理處理器應(yīng)該是無狀態(tài)的,僅使用本地作業(yè)執(zhí)行上下文將狀態(tài)從一個(gè)組件傳遞到另一個(gè)組件。 畢竟,即使是踩踏安全的全局變量也不是那么安全,因?yàn)樽鳂I(yè)的數(shù)據(jù)可能在并發(fā)執(zhí)行時(shí)混雜在一起。
3.節(jié)流
使用隊(duì)列(輸入或在批處理程序中)時(shí),您應(yīng)該始終有一個(gè)限制策略。 如果物品的生產(chǎn)率始終高于消耗的物品,那么您將遭受災(zāi)難。 如果排隊(duì)的項(xiàng)目保留在內(nèi)存中,最終將用完它。 如果項(xiàng)目存儲在持久隊(duì)列中,則會用完空間。 因此,您需要一種平衡生產(chǎn)者和消費(fèi)者的機(jī)制。 只要生產(chǎn)率是有限的,您只是要確保您有合適的消費(fèi)者數(shù)量來平衡生產(chǎn)率。
當(dāng)隊(duì)列大小超過給定閾值時(shí),自動(dòng)擴(kuò)展消費(fèi)者就像開始新的消費(fèi)者一樣,是一種合適的自適應(yīng)策略。 當(dāng)隊(duì)列大小低于其他閾值時(shí)殺死使用者,可以釋放不必要的空閑線程。
create-new-consumer閾值應(yīng)大于kill-idle閾值,因?yàn)槿绻鼈兿嗟?#xff0c;則當(dāng)隊(duì)列大小在閾值大小附近波動(dòng)時(shí),您將獲得create-kill抖動(dòng)。
4.存儲工作結(jié)果
在內(nèi)存中存儲作業(yè)結(jié)果不是很周到的事情。 選擇一個(gè)持久性存儲(MongoDb限制的集合)是一個(gè)更好的選擇。
如果結(jié)果保存在內(nèi)存中,而您忘記將它們限制在一個(gè)上限,則批處理處理器最終將耗盡內(nèi)存。 重新啟動(dòng)計(jì)劃程序?qū)⑶宄郧暗墓ぷ鹘Y(jié)果,這是非常有價(jià)值的,因?yàn)檫@是您獲得的唯一反饋。
5.泛濫外部服務(wù)提供商
for(GeocodeRequest geocodeRequest : batchRequests) {mapsService.resolveLocation(geocodeRequest); }這段代碼充斥著您的地圖提供商,因?yàn)橐坏┠瓿梢豁?xiàng)請求,幾乎立即就會發(fā)出一個(gè)新請求,這給他們的服務(wù)器帶來了很大壓力。 如果batchRequests數(shù)目足夠高,那么您可能會被禁止。
您應(yīng)該在兩次請求之間添加一個(gè)短暫的延遲,但是不要讓當(dāng)前的睡眠狀態(tài)變慢,而應(yīng)使用EIP延遲器。
6.對批處理
盡管程序風(fēng)格的編程是大多數(shù)程序員的默認(rèn)思維方式,但許多批處理任務(wù)更適合企業(yè)集成模式設(shè)計(jì)。 使用EIP工具更容易實(shí)現(xiàn)所有上述規(guī)則:
- 消息隊(duì)列
- 投票渠道
- 變形金剛
- 分離器/聚合器
- 延遲器
使用EIP組件可簡化測試,因?yàn)槟淮沃粚W⒂谝豁?xiàng)職責(zé)。 EIP組件通過隊(duì)列傳遞的消息進(jìn)行通信,因此將一個(gè)同步處理通道更改為調(diào)度的線程池只是一個(gè)配置細(xì)節(jié)。
有關(guān)EIP的更多信息,請查看出色的Spring Integration框架。 我已經(jīng)使用了三年了,接種疫苗后,您會更喜歡它而不是過程編程。
翻譯自: https://www.javacodegeeks.com/2013/11/batch-processing-best-practices.html
總結(jié)
- 上一篇: bilibili电脑端加速器(bilib
- 下一篇: Apache Karaf遇到Apache