2017-03-06 41 views
3

我的問題與技術問題相比更具哲理性。如何在異常後的長時間運行過程中使用Doctrine Entity Manager

約Doctrine`s EM的幾句話。它關閉連接,並在其工作期間發生任何異常時自行清除:與數據庫服務器相關的數據庫連接失敗(傳入任務數量較少的長時間運行的使用者的常見情況),SQL語句中的錯誤或其他內容,或者EM本身。此EM實例完全無法使用後。

所以,真實的例子:我有一個隊列和消費者,that`s運行作爲控制檯工人並等待任務。消費者旁邊的依賴:

  • 的EntityManager(EM)
  • 服務1 - >有來自EM和學說Repository1
  • 客服2依賴 - >具有EM和學說Repository2依賴
  • ServiceN - >具有依賴性和EM和Doctrine RepositoryN

如果EM服務失敗 - 取決於此EM的服務(1-N)和存儲庫(1-N)在調用時也會拋出錯誤,因爲EM不再有效合作rrectly。我應該在這種情況下做什麼?

  1. 「讓 - 它碰撞」:工人stoppped錯誤,後來被 supervisord重新加載。導致 logs \ stderr中無用錯誤的數量增加。
  2. 在每次迭代中都會用$connection->ping()做一些魔術:實際上,ping()只是執行SELECT 1;,所以,這導致 增加了無用查詢數量到DB服務器。
  3. 和以前一樣,但在EM的情況下,無法對消費者創造新的:在每次迭代執行ping(),如果它失敗了 - 創造新的EM。 但是,消費者使用的所有服務都應該重新創建,因此我需要爲其中的每個服務提供一個工廠。這樣會導致增加消費者的班數 和更復雜的邏輯:在新的每次迭代重建所有 服務(它依賴),或老 EM,或檢測EM再創造和再創造所有的依賴僅在新EM的情況下服務 。但這導致abstaction泄漏:消費者 不應該知道它使用什麼EM實例 - 舊的或新的,並應該不會做這種糟糕的事情。

什麼是處理這個事情的最好方法?

回答

1

我會在這裏分享一些想法。

  1. 「導致log \ stderr中無用錯誤的數量增加」 - 我不認爲這些是無用的錯誤。如果您的軟件引發異常,您應該知道這一點。該軟件的日誌文件在沒有任何異常情況下是最好的,但很少出現這種情況。無論如何,應該調查任何數據庫異常和發生的速率。

  2. 我不會依賴於重建連接,而是依靠主義API來初始化。 This answer有關於如何爲幾個Doctrine2版本做一些細節。

  3. 我覺得這是太多的邏輯來實現,只會使問題複雜化。

如果我選擇,我會選擇#1(讓它崩潰),因爲它是最簡單的,它不會隱藏任何東西。

+1

在「無用的錯誤」我的意思是例外,如「MySQL連接已經走了」,在情況下提出,如果工人不從隊列和超時DB服務器關閉空閒連接收到任何任務。例如,如果連接超時是一分鐘,生成的任務每1.5-2分鐘(真實世界的例子),24小時後我會收到〜720個錯誤\例外。這隻適用於一名工人。此外,supervisord日誌將充滿「噪音」,生成這種「崩潰重啓」週期,並找到真正的錯誤可以更加防不勝防。 – Alex

+1

至於''resetManager()'',我已經使用了這種方法,但是這僅適用於EM和資料庫,通過''$ EM-> getRepository獲得()''。所有其他服務保持不可用,直到用工廠重新創建。 – Alex