为啥 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.2uWSGI 启动参数:
--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 修复。
【讨论】:
我刚刚从 pymongo2.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"
(注意,如果你的连接字符串中有其他参数,需要将?
改为&
)
【讨论】:
用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&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?的主要内容,如果未能解决你的问题,请参考以下文章