我的問題與技術問題相比更具哲理性。如何在異常後的長時間運行過程中使用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。我應該在這種情況下做什麼?
- 「讓 - 它碰撞」:工人stoppped錯誤,後來被 supervisord重新加載。導致 logs \ stderr中無用錯誤的數量增加。
- 在每次迭代中都會用
$connection->ping()
做一些魔術:實際上,ping()
只是執行SELECT 1;
,所以,這導致 增加了無用查詢數量到DB服務器。 - 和以前一樣,但在EM的情況下,無法對消費者創造新的:在每次迭代執行
ping()
,如果它失敗了 - 創造新的EM。 但是,消費者使用的所有服務都應該重新創建,因此我需要爲其中的每個服務提供一個工廠。這樣會導致增加消費者的班數 和更復雜的邏輯:在新的每次迭代重建所有 服務(它依賴),或老 EM,或檢測EM再創造和再創造所有的依賴僅在新EM的情況下服務 。但這導致abstaction泄漏:消費者 不應該知道它使用什麼EM實例 - 舊的或新的,並應該不會做這種糟糕的事情。
什麼是處理這個事情的最好方法?
在「無用的錯誤」我的意思是例外,如「MySQL連接已經走了」,在情況下提出,如果工人不從隊列和超時DB服務器關閉空閒連接收到任何任務。例如,如果連接超時是一分鐘,生成的任務每1.5-2分鐘(真實世界的例子),24小時後我會收到〜720個錯誤\例外。這隻適用於一名工人。此外,supervisord日誌將充滿「噪音」,生成這種「崩潰重啓」週期,並找到真正的錯誤可以更加防不勝防。 – Alex
至於''resetManager()'',我已經使用了這種方法,但是這僅適用於EM和資料庫,通過''$ EM-> getRepository獲得()''。所有其他服務保持不可用,直到用工廠重新創建。 – Alex