我使用 Celery 3.0.15 和 MongoDB 2.4.4 副本集作为后端(pymongo 版本 2.5.1)。我还使用相同的副本集作为主要应用程序数据存储:
CELERY_CONFIG = {
'BROKER_URL': 'mongodb://localhost:27017,localhost:27018,localhost:27019/',
'BROKER_TRANSPORT_OPTIONS': {
'replicaSet': 'test'
}
}
...
conn = MongoReplicaSetClient(
'localhost:27017,localhost:27018,localhost:27019',
replicaSet='test'
)
我可以启动一些工作程序并使用此 conn
实例从 celery 任务内的代码访问数据库。
如果 mongo 主节点关闭并重新选举,celery 工作线程会自动重新连接到新配置。但是,无论我重试多少次以及等待多长时间,所有带有 conn
的后续查询都会返回 AutoReconnect
异常。
分离代理和主数据库的副本集并不能解决问题:工作人员仍然可以正常重新连接,但我无法使用相同的 MongoReplicaSetClient 从任务中访问 mongo。
更新
在AutoReconnect
之后手动调用conn.refresh()
可以解决问题。在这种情况下,MonitorThread
似乎无法正常工作。
最佳答案
原因是 celery 启动它的 worker 的方式。默认情况下,在 3.0.15 中,它使用 fork()
复制父进程的状态,但使 MonitorThread
死亡。解决方案是使用 CELERYD_FORCE_EXECV
选项,强制 celery 使用 execv()
运行工作进程,并使监视器再次活跃起来。
关于mongodb - MongoReplicaSetClient 不会在 celery 工作人员中重新连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17170981/