我的问题比技术问题更哲学。
关于学说的em的几句话。如果工作过程中发生任何例外,它会关闭连接并清除自身:与数据库的连接失败(在传入任务数量少的长期消费者中的常见情况),SQL语句中的错误或其他与DB-Server相关的内容,或他们本身。此EM实例完全无法使用。
因此,现实世界中的示例:我有一个队列和消费者,它是控制台工作人员并等待任务。消费者的下一个依赖性:
- EntityManager(EM)
- service1->具有EM和Doctrine Repository的依赖性1
- Service2->具有EM和Doctrine Repository的依赖性2
- Servicen->具有EM和Doctrine Repositoryn的依赖性
如果EM Service失败了 - 依赖于此EM的服务(1-N)和存储库(1-N)也将在调用时会引发错误,因为EM不再正常工作。在这种情况下我该怎么办?
- " Let-It-Crash":工人错误停止,然后重新加载主管。导致增加无用错误的数量logs stderr。
- 在每次迭代中使用
$connection->ping()
做一些魔术:实际上,ping()
仅执行SELECT 1;
,因此,这导致将无用查询的数量增加到数据库服务器。 - 与以前相同,但是在EM失败的情况下,请在消费者上创建新的:在每次迭代中执行
ping()
,如果失败了 - 创建新的EM。但是,也应重新创建消费者中使用的所有服务,所以我每个人都需要一个工厂。这样会导致数量增加班级和更复杂的消费者逻辑:重新创建所有使用新的或旧的服务(及其依赖性)或检测EM的重新创建并重新创建所有依赖服务仅在新EM的情况下。但这导致弃权泄漏:消费者不应该知道它使用的em实例 - 旧或新的,应该不做这个糟糕的事情。
处理这些事情的最佳方法是什么?
我会在这里分享一些想法。
-
"导致日志 stderr中无用错误的数量" - 我认为这些错误不是无用的错误。如果您的软件引发了异常,则应知道这一点。当软件没有任何例外时,最好是该软件的日志文件,但这很少是这种情况。无论如何,任何数据库异常及其发生的率都应研究。
-
我不会依靠重建连接,而是依靠学说API来初始化自己。此答案有一些有关如何对几个Doctrine2版本执行此操作的细节。
-
我认为这是实现的逻辑太多,只会使事情变得复杂。
如果我要选择,我会选择选项#1(Let-it-Crash),因为它是最简单的,并且不会向我们隐藏任何东西。