2017-03-03 92 views
1

我正在使用NSB的項目,真的很喜歡它,但它是我的第一個NSB解決方案,所以有點小菜鳥。我們有一項工作需要每天處理成員 - 這項工作不會很長,因爲工作很簡單,但可能會影響數千名成員,並且在將來可能會有數十或數十萬名成員。NServiceBus批處理長時間運行的作業

讓這一切都發生在一個單一的處理程序去感覺不對,但有一個處理程序發現受影響的成員,然後發射每個單獨的事件,在相反的方向聽起來有點太多。我可以想到其他一些方法,但是想知道在NSB中是否有處理這種情況的慣用方法?

編輯澄清:我使用Schedule在凌晨3點發送命令,該處理程序將查詢SQL db以獲取需要處理的成員列表。處理將涉及每個成員更新/插入一行或兩行。我的問題是圍繞如何處理NSB內可能的成員列表。

編輯第2部分:工作現在需要每月運行,而不是每天運行。

+0

需要更多的細節請。這項工作的性質是什麼?它是一個SQL工作嗎?計劃任務?一些基於cron的背景?爲什麼預期處理程序會「發現」它需要做哪些工作?當然你應該把所需的工作交給處理者。 –

+0

這是一個SQL工作 - 需要查詢數據庫以查看哪些成員符合特定條件,然後更新併爲每個成員插入一行或兩行 – GoatInTheMachine

+0

@GoatInTheMachine查看我的答案。關於使用NBus的好處是,如果這些事務失敗,它們將會重試,只是確保您的INSERT是冪等的。 –

回答

1

我不會爲此使用傳奇。薩加斯應該是輕量級的,並且是爲協調而非執行工作而設計的。它們由消息開始而不是按計劃進行。

您可以使用內置的scheduler來達到目的。我沒有用過,但看起來很簡單。

你可以這樣做:

  1. 配置命令消息(例如StartJob)每天發送的0300
  2. StartJob處理程序,然後將查詢數據庫來獲取工作。

然後,根據您的要求:

  • 如果你需要同時做所有工作,建立一個單一的命令,在它所有的工作,並將其發送到另一個端點進行處理。如果您使用事務性MSMQ,那麼這將作爲一個單元成功或失敗。
  • 如果您不在意是否只有某些工作成功,請爲每個工作單元創建一個命令,然後分派到端點進行處理。如果需要,可以使用distributor進行擴展。

我工作正在使用NSB項目...我們有需要 每天運行工作...

雖然您可以使用NSB進行這類工作,但這並不是我真正想做的事情。還有很多其他的方法可以使用。 SQL作業或cron作業將是顯而易見的(並且開發速度更快,性能更高,更簡單)。

儘管它確實支持這種用例,但NServiceBus並不是真正爲預定批處理設計的。我會嚴肅質疑你是否應該使用NSB來完成這項任務。

+0

對於一些認識NSB比我更好的人說話,看起來你是正確的,傳奇是不合適的。有一些棘手的業務邏輯和各種其他問題(日誌記錄,審計,事件故事的相關性以及未解決的問題),這意味着我寧願在代碼中執行此操作,而不是SQL,所以我可能會繼續執行每個成員的命令。 – GoatInTheMachine

+1

@GoatInTheMachine - 祝你好運!我已經開始將NSB視爲一種「每一個問題都是釘子」的工具,所以我會一直主張它被用於其最初的目的,即作爲服務總線。 –

+1

我完全理解你的觀點,並且我們過去曾使用過Hangfire等來處理這類事情。 – GoatInTheMachine

1

你提到了一個正在運行的過程,這聽起來像是佐賀的一份工作(見https://docs.particular.net/nservicebus/sagas/)。您可以使用傳奇數據並將檢查點保存在不同的存儲介質(SQL,Mongo等)中。但是,是的,長時間運行然後從傳奇發送消息到個人處理程序絕對是我也會做的。

其他要考慮的是消息延期(Timeout Managers)。例如,讓我們說你處理了x個用戶,但是又想運行這個。 NServiceBus允許您將郵件推遲一段定義的時間,並且郵件將位於隊列中等待分派。

更多信息只是喊,我可以更新我的答案。

+0

謝謝,我會放棄這一點,看起來很合適。 – GoatInTheMachine

+0

什麼開始傳奇?另外,傳奇的最佳實踐是它們輕巧。佐賀處理程序應該只關注發送/發佈。所有的工作都應該在傳奇之外完成。 –

+0

因此,在我看來,一個傳奇對於這個用例來說是矯枉過正的。 –

1

A real NSB解決方案將擺脫在一次運行中處理所有這些記錄的「批處理」作業,並找出哪些操作會導致每個記錄需要處理。

執行此類操作時,您應該發佈NSB事件並將批處理作業重構爲訂閱這些事件的NSB處理程序,以便它可以在執行操作時執行處理,與其餘部分你的過程。

這樣就不會再需要在凌晨3點安排的'開始'消息,因爲所有的工作都已經完成了。

+0

我們正在運行的任務是一項時間敏感的計劃任務 - 不斷實現其他事件背後的工作不可能實現。 – GoatInTheMachine

+0

如果任務對時間敏感,您仍然可以使用相同的機制,但不是保持「批處理」服務整天運行,而是使用計劃任務在凌晨3點啓動它,並在完成時自動停止。 –

+0

使用此模式和舊式批處理作業之間的主要區別是,該流程不需要執行一些昂貴的查詢來確定要完成的工作。這是信息已經以累計事件的形式提供。 –

0

下面是我可能用NServiceBus慣用這種模型的方法:可能有一個名爲PointsExpirationPolicy的傳奇,它會在任何點被授予用戶時啓動。這個傳奇將存儲用戶ID和獎勵點數,並計算點數應該過期的日期/時間。然後它會請求在這些點應該到期的日期/時間發送超時回調消息。當該回調到達時,該事件發送命令以使用戶賬戶中的點數過期。這也可以給你一些靈活的時間和點數到期的邏輯,並消除整個批處理過程。

相關問題