Gevent#

PyMongo支持 Gevent . 打电话给Gevent就行了 monkey.patch_all() 在加载任何其他模块之前:

>>> # You must call patch_all() *before* importing any other modules
>>> from gevent import monkey
>>> _ = monkey.patch_all()
>>> from pymongo import MongoClient
>>> client = MongoClient()

PyMongo使用Python标准库中的线程和套接字函数。Gevent的monkey补丁替换了这些标准函数,因此PyMongo使用非阻塞套接字执行异步I/O,并在greenlet上而不是线程上调度操作。

避免堵塞集线器连接#

默认情况下,PyMongo使用线程来发现和监视服务器的拓扑(请参阅 健康监测 ). 如果你执行 monkey.patch_all() 当应用程序第一次启动时,PyMongo会自动使用greenlets而不是线程。

关闭时,如果应用程序调用 join() 在Gevent的 Hub 在不首先终止这些背景greenlet的情况下,调用 join() 无限期阻塞。所以你 必须关闭或取消引用 任何活跃的 MongoClient 在离开之前。

在某些应用程序框架中,解决此问题的一个示例是,当应用程序收到SIGHUP时,使用信号处理程序结束后台greenlet:

import signal


def graceful_reload(signum, traceback):
    """Explicitly close some global MongoClient object."""
    client.close()


signal.signal(signal.SIGHUP, graceful_reload)

使用1.9.16之前版本的uWSGI的应用程序会受到此问题的影响,或使用 -gevent-wait-for-hub 选项。看到了吗 the uWSGI changelog for details .