我在Django应用程序中同时使用PyMongo和gevent。在制作过程中,它在Gunicorn上托管。
在应用程序启动时,我正在创建一个Connection对象。我有一些后台任务持续运行,每隔几秒钟执行一次数据库操作。
该应用程序还像任何Django应用程序一样提供HTTP请求。
我遇到的问题如下。它只发生在生产中,我无法在我的开发环境中复制它。当我让应用程序空闲一段时间(尽管后台任务仍在运行)时,在第一个HTTP请求(实际上是前几个)上,我执行的第一个"查找"操作永远不会完成。绿绿灯实际上从未恢复。这会导致前几个HTTP请求超时。
我该怎么解决?这是gevent和/或PyMongo中的一个bug吗?
我发现了问题所在。默认情况下,PyMongo没有在连接上定义网络超时,所以发生的情况是池中的连接断开(因为它们有一段时间没有使用)。然后,当我尝试重用一个连接并执行"查找"时,需要很长时间才能检测到该连接已失效(大约15分钟)。当检测到连接已断开时,"find"调用最终抛出一个AutoReconnectError,并生成一个新的连接来替换旧的连接。
解决方案是设置一个小的网络超时(15秒),这样对"find"的调用会阻塞绿绿灯15秒,并引发AutoReconnectError,当重试"find(查找)"时,它会获得一个新的连接,并且操作成功。