为什么PyMongo 3会给出ServerSelectionTimeoutError?

drf*_*nce 34 python mongodb uwsgi mlab pymongo-3.x

我正在使用:

  • 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
Run Code Online (Sandbox Code Playgroud)

我设置我的MongoClient ONE时间:

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

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

result = self.db.jobs.insert_one(job_dict)
Run Code Online (Sandbox Code Playgroud)

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

pymongo.errors.ServerSelectionTimeoutError: No servers found yet
Run Code Online (Sandbox Code Playgroud)

为什么我在通过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
Run Code Online (Sandbox Code Playgroud)

Ber*_*ett 43

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

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

Alo*_*man 15

正如这里提到的:https : //stackoverflow.com/a/54314615/8953378

我添加?ssl=true&ssl_cert_reqs=CERT_NONE到我的连接字符串,它解决了这个问题。

所以而不是:

connection_string = "mongodb+srv://<USER>:<PASSWORD>@<CLUSTER>/<COLLECTION>"
Run Code Online (Sandbox Code Playgroud)

我写:

connection_string = "mongodb+srv://<USER>:<PASSWORD>@<CLUSTER>/<COLLECTION>?ssl=true&ssl_cert_reqs=CERT_NONE"
Run Code Online (Sandbox Code Playgroud)

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

  • 也解决了我的问题。`pymongo==3.12.3` (3认同)
  • 用 `pymongo==3.11.3` 为我解决了这个问题 (2认同)

Gre*_*reg 10

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

   flask/bin/pip uninstall pymongo
   flask/bin/pip install pymongo==2.8
Run Code Online (Sandbox Code Playgroud)

  • `pip install pymongo == 2.8 --upgrade` (6认同)

小智 7

我在 Pymongo 3.5 上遇到了同样的问题 结果用 127.0.0.1 或 mongodb 实例的相应 ip 地址替换 localhost 解决了这个问题。


cru*_*lab 7

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

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

在 MongoAtlas 中,这可以在此页面完成 在此处输入图片说明

我知道已经有针对同一问题的解决方案,但我没有找到对我的情况有帮助的解决方案,因此想发布此信息,以便其他人在遇到与我相同的问题时受益。


ttf*_*man 5

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