1. ホーム
  2. python

[解決済み] PyMongo 3でServerSelectionTimeoutErrorが発生するのはなぜですか?

2022-02-18 05:16:14

質問

使っています。

  • Python 3.4.2
  • PyMongo 3.0.2
  • mongod 2.6.9が動作するmongolab
  • 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を1回だけセットアップしました。

self.mongo_client = MongoClient('mongodb://user:[email protected]:port/mydb')
self.db = self.mongo_client['mydb']

JSONのdictをMongoDBに保存してみる。

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

mongodbへの同じコードパスを実行するユニットテストを経由して動作します。 しかし、CherryPyとuWSGI経由でHTTP POSTを使用して実行すると、次のようになります。

pymongo.errors.ServerSelectionTimeoutError: No servers found yet

CherryPyやuWSGI経由で実行すると、なぜこのような挙動になるのでしょうか? これはおそらくPyMongo 3での新しいスレッドモデルですか?

更新しました。

CherryPyの組み込みサーバを使ってuWSGIとnginxを使わずに実行すると insert_one() が動作します。

1/25 4:53pm EST を更新しました。

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

解決方法は?

で追跡調査しています。 PYTHON-961 . を渡すことで、この問題を回避できるかもしれません。 connect=False のインスタンスを作成するときに、MongoClient のインスタンスを作成します。これにより、バックグラウンドでの接続を最初のデータベース操作が行われるまで延期し、 MongoClient のモニタースレッドの回転とマルチプロセスのフォークの間に起こるレースコンディションを回避できます。