最近我一直试图将Mongoengine和Flask与副本集一起使用。我可以连接但是,当主节点发生变化时,连接会丢失并且有中断。
这是一个可以测试行为的片段。它使用非常有用的http://flip-flop.mlab.com/站点来调试副本集问题
from flask import Flask
from mongoengine import connect
from flask_mongoengine import MongoEngine
import os
db = MongoEngine()
app = Flask(__name__)
class TestDoc(db.Document):
texto = db.StringField()
class ProductionConfig:
def get_conn_data(self):
conn = {
'host':"mongodb://testdbuser:testdbpass@flip.mongolab.com:53117,flop.mongolab.com:54117/testdb?replicaSet=rs-flip-flop",
'replicaSet': 'rs-flip-flop'
}
return conn
import time
app.config['MONGODB_SETTINGS'] = ProductionConfig().get_conn_data()
db.init_app(app)
if __name__ == '__main__':
with app.test_client() as c:
while True:
time.sleep(1)
print(TestDoc.objects().count())
TestDoc(texto="1").save()
我每次主要更改错误时都会收到错误:pymongo.errors.AutoReconnect: connection closed
。
非常感谢!我尝试了几个不同的pyMongo版本但没有成功。任何帮助都会非常非常感谢!
答案 0 :(得分:0)
这里的问题是新主要选举不是即时的。来自the docs:
它有所不同,但副本集通常会选择一个新的主要内容 分钟。
例如,副本成员可能需要10-30秒 设置为声明主要不可访问(请参阅electionTimeoutMillis)。一 剩下的第二个人举行选举以选举自己为一个 新的小学。在选举期间,群集不可用 写入。
选举本身可能需要10-30秒。
在主要下行和副本被选为新主要之间的时间内,没有可以接受写入的连接(因为它们必须进入初选)。
但是,您可以对代码执行一些操作,以使其在这些情况下更具弹性。
首先,您应该在连接上设置读取首选项(more info here):
conn = {
'host':"mongodb://testdbuser:testdbpass@flip.mongolab.com:53117,flop.mongolab.com:54117/testdb",
'replicaSet': 'rs-flip-flop',
'read_preference': ReadPreference.SECONDARY_PREFERRED
}
这意味着在选举期间读取应该非常强大。
不幸的是,如果在try
块中包含所有写入,那么如果在选举期间尝试写入代码,则代码将会失败。
这应该不是问题的例子,因为(假设你正在烧瓶路线中写作),网络服务器将抛出500错误响应。当你再次从烧瓶请求路线时,选举应该完成,而mongoengine将写入新的初级。