如何检查 MongoDB 实例的客户端是否有效?

问题描述 投票:0回答:8

特别是,我目前正在尝试使用以下函数检查与客户端的连接是否有效:

def mongodb_connect(client_uri):
    try:
        return pymongo.MongoClient(client_uri)
    except pymongo.errors.ConnectionFailure:
         print "Failed to connect to server {}".format(client_uri)

然后我像这样使用这个函数:

def bucket_summary(self):
    client_uri = "some_client_uri"
    client = mongodb_connect(client_uri)
    db = client[tenant_id]
    ttb = db.timebucket.count() # If I use an invalid URI it hangs here

如果给出了无效的 URI,有没有办法在最后一行捕获并抛出异常?我最初认为这就是 ConnectionFailure 的用途(因此连接时可能会捕获),但我错了。

如果我使用无效的 URI 运行程序,该程序无法运行,则发出 KeyboardInterrupt 会产生:

File "reportjob_status.py", line 58, in <module>
tester.summarize_timebuckets()
File "reportjob_status.py", line 43, in summarize_timebuckets
ttb = db.timebucket.count() #error
File "/Library/Python/2.7/site-packages/pymongo/collection.py", line   1023, in count
return self._count(cmd)
File "/Library/Python/2.7/site-packages/pymongo/collection.py", line 985, in _count
with self._socket_for_reads() as (sock_info, slave_ok):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/Library/Python/2.7/site-packages/pymongo/mongo_client.py", line 699, in _socket_for_reads
with self._get_socket(read_preference) as sock_info:
File  "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/Library/Python/2.7/site-packages/pymongo/mongo_client.py", line 663, in _get_socket
server = self._get_topology().select_server(selector)
File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 121, in select_server
address))
File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 106, in select_servers
self._condition.wait(common.MIN_HEARTBEAT_INTERVAL)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 358, in wait
_sleep(delay)
python mongodb pymongo
8个回答
90
投票

serverSelectionTimeoutMS
pymongo.mongo_client.MongoClient
关键字参数控制驱动程序尝试连接到服务器的时间长度。默认值为 30 秒。

将其设置为与您的典型连接时间兼容的非常低的值1以立即报告错误。之后您需要查询数据库以触发连接尝试:

>>> maxSevSelDelay = 1 # Assume 1ms maximum server selection delay
>>> client = pymongo.MongoClient("someInvalidURIOrNonExistantHost",
                                 serverSelectionTimeoutMS=maxSevSelDelay)
//                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> client.server_info()

这会提高

pymongo.errors.ServerSelectionTimeoutError

¹ 显然

serverSelectionTimeoutMS
设置为
0
甚至可能在您的服务器具有非常低延迟的特定情况下工作(例如负载非常轻的“本地”服务器的情况)


由您来捕获该异常并正确处理它。类似的东西:

try: client = pymongo.MongoClient("someInvalidURIOrNonExistantHost", serverSelectionTimeoutMS=maxSevSelDelay) client.server_info() # force connection on a request as the # connect=True parameter of MongoClient seems # to be useless here except pymongo.errors.ServerSelectionTimeoutError as err: # do whatever you need print(err)

将显示:

No servers found yet
    

27
投票
您好,要了解连接是否已建立,您可以这样做:

from pymongo import MongoClient 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")
    

4
投票

服务器选择超时MS

这定义了在抛出异常之前阻止服务器选择的时间 例外。默认值为 30,000(毫秒)。一定是 可在客户端级别进行配置。它不能在 数据库对象、集合对象的级别或 个别查询。

选择此默认值足以满足典型服务器的需要 初选完成。随着服务器速度的提高 选举,这个数字可能会向下修改。

能够容忍服务器选择时较长延迟的用户 拓扑不断变化可以将其设置得更高。想要“失败”的用户 fast”,当拓扑处于变化状态时,可以将其设置为一个较小的数字。

serverSelectionTimeoutMS 为零可能在某些情况下具有特殊含义 司机;本规范中未定义零的含义,但所有驱动程序 应记录零的含义。

https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#serverselectiontimeoutms

# pymongo 3.5.1 from pymongo import MongoClient from pymongo.errors import ServerSelectionTimeoutError client = MongoClient("mongodb://localhost:27000/", serverSelectionTimeoutMS=10, connectTimeoutMS=20000) try: info = client.server_info() # Forces a call. except ServerSelectionTimeoutError: print("server is down.") # If connection create a new one with serverSelectionTimeoutMS=30000
    

2
投票

serverSelectionTimeoutMS

 对我不起作用(Python 2.7.12、MongoDB 3.6.1、pymongo 3.6.0)。 
A. Jesse Jiryu DavisGitHub问题中建议我们首先尝试套接字级连接作为试金石。这对我有用。

def throw_if_mongodb_is_unavailable(host, port): import socket sock = None try: sock = socket.create_connection( (host, port), timeout=1) # one second except socket.error as err: raise EnvironmentError( "Can't connect to MongoDB at {host}:{port} because: {err}" .format(**locals())) finally: if sock is not None: sock.close() # elsewhere... HOST = 'localhost' PORT = 27017 throw_if_mongodb_is_unavailable(HOST, PORT) import pymongo conn = pymongo.MongoClient(HOST, PORT) print(conn.admin.command('ismaster')) # etc.

有很多问题无法捕获,但如果服务器未运行或无法访问,它会立即向您显示。


0
投票
也可以这样检查:

from pymongo import MongoClient from pymongo.errors import OperationFailure def check_mongo_connection(client_uri): connection = MongoClient(client_uri) try: connection.database_names() print('Data Base Connection Established........') except OperationFailure as err: print(f"Data Base Connection failed. Error: {err}") check_mongo_connection(client_uri)
    

0
投票
对于

pymongo >= 4.0 首选方法是使用 ping

 命令 
而不是已弃用的 ismaster
:

from pymongo.errors import ConnectionFailure client = MongoClient() try: client.admin.command('ping') except ConnectionFailure: print("Server not available")
要处理身份验证失败,请包含 

OperationFailure

:

except OperationFailure as err: print(f"Database error encountered: {err}")
来源:

mongo_client.py


0
投票
def mongo_available(): maxsevseldelay = 1 # Assume 1ms maximum server selection delay client = pymongo.MongoClient('mongodb://localhost:27017,localhost2:27017',serverSelectionTimeoutMS=maxsevseldelay) try: # The ping command is cheap and does not require auth. client.admin.command('ping') return True, "Mongo connection working fine" except ConnectionFailure: return False, "Mongo Server not available" mongo_available() (False, 'Mongo Server not available')
    

0
投票
这将循环 30 秒,尝试 ping 到您的部署。对我来说效果很好。

# Connect to Mongo client client = MongoClient(mongo_connection_string) # Send a ping to confirm a successful connection end_time = time.time() + 30 while time.time() < end_time: try: client.admin.command('ping') print("Pinged your deployment. You successfully connected to MongoDB!") break # Successful connection, exit the loop except Exception as e: print(f"Failed to connect: {e}")
    
© www.soinside.com 2019 - 2024. All rights reserved.