为啥 PyMongo 3 给出 ServerSelectionTimeoutError?

Posted

技术标签:

【中文标题】为啥 PyMongo 3 给出 ServerSelectionTimeoutError?【英文标题】:Why is PyMongo 3 giving ServerSelectionTimeoutError?为什么 PyMongo 3 给出 ServerSelectionTimeoutError? 【发布时间】:2015-09-10 21:02:54 【问题描述】:

我正在使用:

Python 3.4.2 PyMongo 3.0.2 mongolab 运行 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 字典保存到 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 EST:

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

这导致以下堆栈跟踪:

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

【问题讨论】:

我在类似的设置上也遇到了这个问题。你找到答案了吗? 什么都没有……还没有回到调试阶段。 要我开始赏金吗?您可以回答后续问题吗?我自己完全陷入了这个困境。 这个有用吗? blog.fejes.ca/?p=2496我不确定它如何应用于 uwsgi? 赏金会很棒。我尝试在 mongodb google 组中发帖,但我的问题从未发布。 【参考方案1】:

我通过从 pymongo 3.0 降级到 2.8 为自己解决了这个问题。不知道发生了什么。

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

【讨论】:

pip install pymongo==2.8 --upgrade 截至 2016 年 11 月 22 日,使用 Debian Jessie(即 pymongo 3.3.x 和最新的 mongodb-org 即 3.2 之类的)出现相同的错误,即使使用 connect=False 标志也是如此。降级到 pymongo 2.8 解决了这个问题。 我使用了pymogo==3.7.2,我卸载它并安装了pymongo==2.8。但这对我不起作用。【参考方案2】:

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

【讨论】:

这可能是一个愚蠢的问题,但究竟是如何做到的? 如果我们在mongodb中使用身份验证,此解决方案将失败。是否有任何其他解决方案 这对我不起作用——Ubuntu 18.04 下的 pymongo 3.7.2 和 python 3.6.7——可以连接并执行提取,但是当我尝试简单插入时会出现 ServerSelectionTimeoutError 异常。调试器显示连接资源的所有三个阶段都引用了相同的 SSL 证书文件。 @SARose, mongo = MongoClient(MONGO_CONNECTION_STRING, connect=False)【参考方案3】:

这已在PyMongo 中通过this pull_request 修复。

【讨论】:

我刚刚从 pymongo 2.6.2 升级到 3.2.2 并收到此错误:ServerSelectionTimeoutError: No servers found yet。在 Ubuntu 16.04 上运行 MongoDB 3.2.5、Python 2.7、Bottle 0.12.9。修复程序是否在 3.2.2 以外的版本中? 这不是修复,这个 PR 只是启用在接受的答案中提到的 workaround:***.com/a/31194981/1446048【参考方案4】:

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

【讨论】:

【参考方案5】:

我也遇到过。

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

我通过在 uwsgi 中添加 --lazy-apps 参数来解决这个问题,这样可以避免“fork safe”问题。

正在查看 uwsgi 文档preforking-vs-lazy-apps-vs-lazy。

注意,不确定这两者是否有正向联系。

【讨论】:

【参考方案6】:

我在 Pymongo 3.5 上遇到了同样的问题 原来用 127.0.0.1 或 mongodb 实例的相应 IP 地址替换 localhost 可以解决问题。

【讨论】:

也为我修复了(pymongo==3.6,电机)【参考方案7】:

首先设置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 prompt]

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/

【讨论】:

【参考方案8】:

我不确定您是否将 MongoDB 与 AWS 云服务配对使用。但如果你是,我发现你必须指定你希望 MongoDB 可以访问的 IP 地址。

所以你需要做的是添加你的主机服务器的 IP 地址以允许进入。

在 MongoAtlas 中,可以在此页面完成

我知道已经有相同问题的解决方案,但我没有找到对我的情况有帮助的解决方案,所以想发布此内容,以便其他人在遇到与我相同的问题时可以从中受益。

【讨论】:

【参考方案9】:

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

    修改 mongod.conf 文件:

    vi /etc/mongod.conf
    

    你可以在127.0.0.1后面添加mongodb服务器ip地址,保存:

    net:
      port:27017
      bindIp:127.0.0.1,mongodb server ip
    

    在终端:

    sudo service mongod restart

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

【讨论】:

【参考方案10】:

出现该错误是因为后台没有运行 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()

【讨论】:

【参考方案11】:

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

【讨论】:

【参考方案12】:

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

【讨论】:

【参考方案13】:

这里提到:https://***.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"

(注意,如果你的连接字符串中有其他参数,需要将?改为&amp;

【讨论】:

pymongo==3.11.3为我解决了这个问题 用 Flask-Pymongo 2.3.0 为我解决了这个问题【参考方案14】:

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

【讨论】:

【参考方案15】:

当您实例化客户端时,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")

【讨论】:

【参考方案16】:

我今天也面临同样的异常。在我的情况下,代理设置可能会阻止连接,因为我可以通过更改我的 wifi 来建立与 mongodb 的成功连接。即使这个问题已被标记为已解决,它也有望缩小其他问题的范围。

【讨论】:

【参考方案17】:

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

【讨论】:

【参考方案18】:

我在开发过程中遇到了同样的问题。这是因为 mongodb 没有在我的本地机器上运行(sudo systemctl restart mongod 让 mongodb 在 Ubuntu 上运行)。

【讨论】:

【参考方案19】:

就我而言

我使用的是 Mongo Atlas 路由器重启后我得到了另一个 IP 地址

因此我必须通过

在 Mongo Atlas 设置中将该 IP 添加到白名单
MongoAtlas website -> Network Access -> IP Whitelist -> Add IP Address -> Add Current IP Address

然后等待 IP 地址的状态变为 Active,然后再次尝试运行应用程序

如果您使用 repl.it 服务器进行托管,只需添加您用于配置服务器的主机 ip,对我来说是 0.0.0.0,这是最常见的

【讨论】:

【参考方案20】:

我只是在network access 选项卡中添加了我当前的 IP 地址,因为它会自动更改。把之前的删了,IP地址略有变化。

【讨论】:

【参考方案21】:

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

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

【讨论】:

【参考方案22】:

当我将服务中的 MongoDB 切换到之前停止的运行时,这个问题就解决了。

【讨论】:

【参考方案23】:

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

【讨论】:

【参考方案24】:

转到您的 Atlas 控制台 > 网络访问,然后添加您的客户端 IP 地址, 前任。 0.0.0.0/00 (注意:所有客户端ip都可以访问你的数据库)

【讨论】:

【参考方案25】:

我一直在努力解决同样的问题。读取和插入都没有工作,ServerSelectionTimeoutError 失败。

我一直在 Ubuntu 18.04 LTS 上使用 pymongo==3.11.4。 尝试使用connect=False,将额外的?ssl=true&amp;ssl_cert_reqs=CERT_NONE 选项传递给我的连接字符串和上面列出的其他建议。就我而言,它们不起作用。

最后简单尝试升级到pymongo==3.12.1,连接开始工作,没有通过connect=false,其他extra arguments建议。

    login = '<USERNAME>'
    password = '<PASSWORD>'
    host = '*.mongodb.net'
    db = '<DB>'
    uri = f'mongodb+srv://login:password@host/db?retryWrites=true&w=majority'
    client = MongoClient(uri, authsource='admin')#, connect=False)
    collection = client.db.get_collection('collection_name')
    # t = collection.find_one('hello': '1')
    t = collection.insert_one('hello': '2')
    print(t)

【讨论】:

【参考方案26】:

我今天遇到了这个问题。我设法通过以下方式处理它:

安装 dnspython 库 > 进入 MongoDB 网页 > 登录 > 安全 > 网络访问 > 添加 IP 地址 > 添加我的请求来自的 IP 地址。

希望这可以帮助某人。

【讨论】:

【参考方案27】:

确保您输入的是用户密码,而不是 MongoDB 帐户密码。我遇到了类似的问题。就我而言,我错误地输入了 MongoDB 帐户密码而不是用户密码。

【讨论】:

此类情况与MongoDB的配置有关。最好不要将系统用户用于非系统应用程序。当前问题的问题原因不是身份验证子系统。乍一看,问题出在连接性内部(路由器、防火墙、*** 的配置或提供商问题),也可能在数据库托管提供商的安全布局中。也许主机使用了非标准的 TCP 端口。【参考方案28】:

我遇到了同样的问题.. 2 分钟前运行良好的代码给出了这个错误。我在谷歌上寻找解决方案大约 30 分钟,它自动得到修复。问题可能是我的家庭互联网连接。只是猜测,但如果您没有对代码或任何其他配置文件进行任何更改,最好等待一段时间并重试。

【讨论】:

这并不能真正回答问题。如果您有其他问题,可以点击 进行提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review

以上是关于为啥 PyMongo 3 给出 ServerSelectionTimeoutError?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 PyMongo 在列出集合时给出不支持的投影选项:$substr?

为啥我的 PyMongo 查询中出现无效错误

为啥使用整数作为 pymongo 的键不起作用?

为啥这个 pymongo 子文档找不到工作?

为啥这个 pymongo 子文档找不到工作?

MongoDB(PyMongo)分页具有不同的不给出一致的结果