为什么PyMongo 3会给出ServerSelectionTimeoutError?

时间:2015-06-24 15:11:21

标签: python mongodb uwsgi mlab pymongo-3.x

我正在使用:

  • Python 3.4.2
  • PyMongo 3.0.2
  • mongolab running mongod 2.6.9
  • uWSGI 2.0.10
  • CherryPy 3.7.0
  • nginx 1.6.2
uWSGI启动参数:

--socket 127.0.0.1:8081 --daemonize --enable-threads --threads 2 --processes 2

我设置MongoClient一次:

self.mongo_client = MongoClient('mongodb://user:pw@host.mongolab.com:port/mydb')
self.db = self.mongo_client['mydb']

我尝试将一个JSON dict保存到MongoDB:

result = self.db.jobs.insert_one(job_dict)

它通过单​​元测试工作,该测试执行与mongodb相同的代码路径。但是,当我使用HTTP POST通过CherryPy和uWSGI执行时,我得到了这个:

pymongo.errors.ServerSelectionTimeoutError: No servers found yet

为什么我在使用CherryPy和uWSGI运行时会看到这种行为?这可能是PyMongo 3中的新线程模型吗?

更新

如果我使用CherryPy内置服务器在没有uWSGI和nginx的情况下运行,insert_one()可以运行。

更新1/25美国东部时间下午4点53分

在PyMongo中添加一些调试后,topology._update_servers()知道服务器'myserver-a.mongolab.com'的server_type = 2。但是server_description.known_servers()服务器'myserver.mongolab.com'

的server_type = 0

这会导致以下堆栈跟踪:

result = self.db.jobs.insert_one(job_dict)
File "/usr/local/lib/python3.4/site-packages/pymongo/collection.py", line 466, in insert_one
with self._socket_for_writes() as sock_info:
File "/usr/local/lib/python3.4/contextlib.py", line 59, in __enter__
return next(self.gen)
File "/usr/local/lib/python3.4/site-packages/pymongo/mongo_client.py", line 663, in _get_socket
server = self._get_topology().select_server(selector)
File "/usr/local/lib/python3.4/site-packages/pymongo/topology.py", line 121, in select_server
address))
File "/usr/local/lib/python3.4/site-packages/pymongo/topology.py", line 97, in select_servers
self._error_message(selector))
pymongo.errors.ServerSelectionTimeoutError: No servers found yet

23 个答案:

答案 0 :(得分:39)

我们正在调查此问题,已在PYTHON-961中进行了跟踪。在创建MongoClient实例时,您可以通过传递 connect = False 来解决此问题。这推迟了后台连接,直到尝试第一次数据库操作,避免了我怀疑MongoClient的监视器线程和多进程分叉之间的竞争条件。

答案 1 :(得分:9)

我通过从pymongo 3.0降级到2.8来为自己修复它。不知道发生了什么。

   flask/bin/pip uninstall pymongo
   flask/bin/pip install pymongo==2.8

答案 2 :(得分:4)

我和Pymongo 3.5有同样的问题 原来用127.0.0.1替换localhost或你的mongodb实例的相应ip地址解决了这个问题。

答案 3 :(得分:2)

如此处所述:https://stackoverflow.com/a/54314615/8953378

我在连接字符串中添加了?ssl=true&ssl_cert_reqs=CERT_NONE,并解决了该问题。

所以而不是:

connection_string = "mongodb+srv://<USER>:<PASSWORD>@<CLUSTER>/<COLLECTION>"

我写道:

connection_string = "mongodb+srv://<USER>:<PASSWORD>@<CLUSTER>/<COLLECTION>?ssl=true&ssl_cert_reqs=CERT_NONE"

(请注意,如果连接字符串中还有其他参数,则需要将?更改为&

答案 4 :(得分:1)

我不确定您是否使用与AWS Cloud服务配对的MongoDB。但如果你是,我发现你必须指定你希望MongoDB有权访问哪个IP地址。

因此,您需要添加主机服务器的IP地址以允许输入。

在MongoAtlas中,可以在此页面上完成此操作 enter image description here

我知道已经有同样问题的解决方案了,但是我找不到能够帮助我解决问题的解决方案,所以想发布这个问题,所以如果他们遇到与我相同的问题,其他人也会受益。

答案 5 :(得分:1)

我今天也面临着同样的例外。以我为例,代理设置可能阻止了连接,因为我可以通过更换wifi 建立与mongodb的成功连接。即使此问题已被标记为已解决,也有望将其缩小到其他问题。

答案 6 :(得分:0)

就我而言,我只将我的 ip 允许列表设置为 0.0.0.0 允许任何地方,但您可以使用“我的 ip 是什么”设置您的 ip 并将其复制粘贴到网络访问 > 添加 ip

答案 7 :(得分:0)

我在 Windows 上遇到了同样的错误,我刚刚启动了 MongoDB 服务

  • 打开服务 ctrl+R 然后输入 services.msc 然后回车

答案 8 :(得分:0)

我只是在network access标签中添加了当前IP地址,因为它是自动更改的。删除较早的版本,IP地址略有更改。

答案 9 :(得分:0)

就我而言

  • 我正在使用Mongo Atlas
  • 路由器重启后,我又获得了IP地址

因此,我必须通过

将该IP添加到Mongo Atlas设置的白名单上

MongoAtlas website -> Network Access -> IP Whitelist -> Add IP Address -> Add Current IP Address

然后等待IP地址的状态更改为“活动”,然后尝试再次运行该应用程序

答案 10 :(得分:0)

在开发过程中遇到了同样的问题。这是由于mongodb不在我的本地计算机上运行(sudo systemctl restart mongod才能使mongodb在Ubuntu上运行)。

答案 11 :(得分:0)

开发人员正在调查此问题,该问题已在PYTHON-961中进行了跟踪。您可以通过手动运行mongod.exe并对其进行监视来解决此问题。当控制台冻结时,会出现此问题,如果mongod控制台卡住,则可以按Enter键。在开发人员修复此错误之前,这是目前最简单的解决方案。

答案 12 :(得分:0)

实例化客户端时,

pymongo 3不会告诉您连接失败。您可能没有连接。

https://api.mongodb.com/python/3.5.1/api/pymongo/mongo_client.html

”(如果它们不可用,则不再引发ConnectionFailure )。 您可以检查服务器是否可用,例如:“

from pymongo.errors import ConnectionFailure
client = MongoClient()
try:
    # The ismaster command is cheap and does not 
require auth.
    client.admin.command('ismaster')
except ConnectionFailure:
    print("Server not available")

答案 13 :(得分:0)

我在mongod.conf中注释掉bindIP变量,而不是允许所有连接(必须输入0.0.0.0)。当然,要小心后果。

答案 14 :(得分:0)

我通过安装dnspython(pip install dnspython)解决了这个问题。问题是:“必须安装“ dnspython”模块才能使用mongodb + srv:// URI”

答案 15 :(得分:0)

我正在使用pymongo 3.2,遇到了相同的错误,但是在我的情况下这是一个配置错误。启用授权后,我忘记更新URL中的端口,该端口最终导致连接超时。可能值得一提的是,可能需要?authSource,因为它通常不同于存储应用程序数据的数据库。

答案 16 :(得分:0)

发生此错误是因为没有MongoDB服务器在后台运行。要运行MongoDB服务器,请打开cmd或anaconda提示符并输入以下命令:-

"C:\Program Files\MongoDB\Server\3.6\bin\mongod.exe"

然后运行

import pymongo
myclient = pymongo.MongoClient()    
mydb = myclient["mydatabase"]
myclient.list_database_names()

答案 17 :(得分:0)

也许您可以尝试将服务器IP地址添加到mongod.conf文件中。 如果您使用linux(ubuntu)操作系统,则可以尝试我的解决方案:

  1. 修改mongod.conf文件:

    vi /etc/mongod.conf
    

    您可以在127.0.0.1之后添加mongodb服务器ip地址,并保存:

    net:
      port:27017
      bindIp:127.0.0.1,mongodb server ip
    
  2. 在终端:

    sudo service mongod restart

现在,您可以尝试使用pymongo MongoClient连接mongodb。

答案 18 :(得分:0)

  • 首先设置MongoDB环境。

  • 在CMD上运行 - “C:\ Program Files \ MongoDB \ Server \ 3.6 \ bin \ mongod.exe”

  • 打开另一个CMD并运行它 - “C:\ Program Files \ MongoDB \ Server \ 3.6 \ bin \ mongo.exe”

然后你可以使用 pymongo [anaconda提示]

import pymongo
from pymongo import MongoClient

client = MongoClient()
db = client.test_db
collection = db['test_coll']

参考 - https://docs.mongodb.com/tutorials/install-mongodb-on-windows/

答案 19 :(得分:0)

我也遇到了这个。

这可能是由于pymongo3 isn't fork safe

我通过向uwsgi添加--lazy-apps param来解决这个问题,这可以避免“fork safe”问题。

查看uwsgi doc preforking-vs-lazy-apps-vs-lazy

注意,这两个没有确定的正面联系。

答案 20 :(得分:0)

我遇到了同样的问题,最后我发现客户端IP被mongo服务器的防火墙阻止了。

答案 21 :(得分:-1)

如果有帮助,我可以通过replace来解决:

from flask.ext.mongoengine import MongoEngine

作者:

from flask_mongoengine import MongoEngine

答案 22 :(得分:-1)

已在PyMongo this pull_request修复此问题。