Mongoengine 连接到 atlas 还没有找到副本集成员

Web*_*ube 6 python pymongo uwsgi mongodb-atlas

在一个工作生产应用程序连接到本地 mongo 之后,我们决定转移到Mongo Atlas. 这导致了生产错误。

Our stack is docker -> alping 3.6 -> python 2.7.13 -> Flask -> uwsgi (2.0.17) -> nginx running on aws
flask-mongoengine-0.9.3 mongoengine-0.14.3 pymongo-3.5.1
Run Code Online (Sandbox Code Playgroud)

在 中启动应用程序时staging/productionuwsgi正在发送No replica set members found yet.

我们不知道为什么。

我们尝试了不同的连接设置connect: False,这是延迟连接,这意味着不是初始化,而是第一次查询。它导致 nginxresource temporarily unavailable在我们的某些应用程序上因错误而失败。我们不得不多次重新启动应用程序才能最终开始服务请求。

我认为问题出在 pymongo 以及它不是fork-safe http://api.mongodb.com/python/current/faq.html?highlight=thread#id3 并且uwsgi正在使用叉子的事实

我怀疑这可能与我的应用程序的初始化方式有关。可能由 aginst Using PyMongo with Multiprocessing 这里是应用程序初始化代码:

from app import FlaskApp
from flask import current_app

app = None

from flask_mongoengine import MongoEngine

import logging

application, app = init_flask_app(app_instance, module_name='my_module')


def init_flask_app(app_instance, **kwargs):
    app_instance.init_instance(environment_config)

    application = app_instance.get_instance()
    app = application.app
    return application, app 

# app_instance.py
import FlaskApp
def init_instance(env):
    global app
    app = FlaskApp(env)
    return app


def get_instance():
    if globals().get('app') is None:
        app = current_app.flask_app_object
    else:
        app = globals().get('app')

    assert app is not None
    return app




class FlaskApp(object):

    def __init__(self, env):
        .....

        # Initialize the DB
        self.db = Database(self.app)
        ....
        # used in app_instance.py to get the flask app object in case it's None
        self.app.flask_app_object = self    

    def run_server(self):
        self.app.run(host=self.app.config['HOST'], port=self.app.config['PORT'], debug=self.app.config['DEBUG'])



class Database(object):

    def __init__(self, app):
        self.db = MongoEngine(app)

    def drop_all(self, database_name):
        logging.warn("Dropping database %s" % database_name)
        self.db.connection.drop_database(database_name)


if __name__ == '__main__':
    application.run_server()
Run Code Online (Sandbox Code Playgroud)

帮助调试这将不胜感激!