我正在使用Celery和MongoEngine作为我的Django应用程序的一部分。
当芹菜@shared_task通过mongoengine模型类访问mongodb数据库时,我收到此警告:
UserWarning: MongoClient opened before fork. Create MongoClient with
connect=False,or create client after forking. See PyMongo's
documentation for details:
http://api.mongodb.org/python/current/faq.html#using-pymongo-with-multiprocessing
它显然与多处理和 pyMongo 有关,这是 mongoengine 的基础。
我的问题是:
避免mongoengine此问题的最佳策略是什么?
请注意,我正在settings.py
中使用mongoengine连接到mongodb:
mongoengine.connect('my_mongo_database_name', alias='default')
在网上搜索了一下后,我发现可以将其他参数传递给mongoengine.connect
函数,这些额外的参数将被传递给底层PyMongo
类和函数。
所以我简单地将mongoengine.connect()
调用编辑为以下内容:
mongoengine.connect('my_mongo_database_name', alias='default', connect=False)
警告不再出现。尽管如此,我不确定这是处理警告的最佳方法。如果您有更好的答案,请发布它,我很乐意测试它并最终接受它。
这是我学到的:
- Celery 有"子工作线程",当您运行
celery -A app worker
它会启动 1 个具有许多子工作线程的工作线程时,默认情况下子工作线程的数量等于处理器中的内核数量 - 默认情况下,Celery 使用预分叉机制来生成"子工作者",这意味着它使用 fork 为每个"子工作线程"创建一个新进程
- 我正在信号
@signals.worker_init.connect
上初始化我的 mongo db 连接,但似乎在进行分叉之前,这种信号是在父进程上执行的。 - 要在分叉后初始化 mongo db 连接,我需要改用信号
@signals.worker_process_init.connect
。
它看起来像这样:
@signals.worker_process_init.connect
def on_worker_process_init(**kwargs):
DatabaseConnection()