2017-07-02 75 views
1

我正在構建一個數據庫,其中一些表將填充爲「使用它或丟失」場景的自動應用程序流。這意味着數據將通過Webhook(PayPal IPN)進入,如果我的RDBMS拒絕INSERT,那麼數據將丟失,即沒有操作員檢查/更正數據並重試。如何確保來自webhook的數據的一致性

一個簡單的解決方案是通過排除NOT NULL甚至可能使字段基於文本來使DB字段儘可能簡單。

一致性問題依然存在。我怎樣才能確保這一點?是否應該包含可能包含在數據庫中的檢查,並在出現問題時記錄警告。

現實情況是,如果WebHook服務發生變化,事情只會中斷,但我想爲這種情況做好準備。

UPDATE:

我想另一個辦法可以是逐字緩存中的NoSQL存儲中的所有傳入的網絡掛接的消息。不管上述問題,這可能是一個好主意。

+0

嘗試使用''commit''和''rollback''命令https://www.tutorialspoint.com/sql/sql-transactions.htm – Dimgold

+0

我認爲你錯過了這個問題。回滾之後我會做什麼? – conor

回答

0

這一切都取決於它是多麼重要的是你不失去這個事件/數據。

由於網絡問題或其他問題,webhook永遠都不會被調用,但是如果我們假設PayPal負責確保您的服務器上的webhook最終被調用(即他們已經重新嘗試了它們側,如果事情失敗),你可以接近100%保證,你不會失去你身邊的數據,通過執行以下的一種或多種:

  • 在servlet /應用receiveing網絡掛接在您身邊,確保您儘可能少地使用它,除了可能驗證數據以確保它以一致的形式存儲在您的身邊。有人可能會爭辯說,如果您想在以後重新播放它們,您還應該堅持使用意外數據的無效事件或事件。

  • 如果有代替(如RabbitMQ的,卡夫卡,卡桑德拉,Redis的,或類似的)消息代理/隊列系統或其它高庫存狀況分佈式數據存儲,則應該有發送事件。您可能會選擇始終這樣做,或者僅在直接向數據庫執行寫操作失敗時才執行此操作,但爲了簡單起見,最好始終將事件放在隊列中,並有一個單獨的進程從隊列中讀取並寫入數據到SQL數據庫。

  • 如果您沒有隊列系統,或者將事件存儲在隊列系統中失敗,則可以在處理webhook的節點上的本地磁盤¹上保留事件。這種回退可能有助於您在寫入數據庫和/或隊列系統失敗時恢復「丟失」事件。

  • 在一個單獨的進程中,從隊列或其他分佈式存儲中獲取事件,並將其插入到數據庫中。如果寫入數據庫成功,這個過程只應該確認隊列上的消息,否則消息不應該被確認,因此消息可以被重新處理。

還有更多的這些技巧可以讓你更接近100%保證永遠不會錯過任何事件。最後,一切都會失敗,如果你想要一些非常健壯的東西,你應該設計它,期望任何事情都會在某個時候失敗。

但是,即使yuo具有分佈式消息隊列,如果寫入隊列失敗並且寫入本地磁盤失敗,則可能會丟失數據。在這種情況下恢復數據的唯一方法是讓PayPal重新播放該事件並使用相同的數據再次調用webhook,或者從PalPal手動檢索相同的數據(如果可能)。

BTW:是否使用一個隊列,或只是一個「啞」分佈式數據存儲庫,用於存儲事件取決於你是否在意處理順序,同一事件多次處理等

¹如果您登錄在webhook節點上處理數據時,您可以免費獲得本地磁盤持久性,但這取決於您是否能夠實際記錄事件中的所有數據,如果事件包含敏感數據,這可能不可行。如果您在plcace中有某種類型的日誌傳送或分佈式日誌記錄服務器,這也可能(部分)保護您在webhook節點上的磁盤失敗或節點本身失敗(即,虛擬/雲服務器正在重新啓動並丟失其磁盤) 。