2012-08-28 85 views
3

我从Django应用程序一起使用PyMongo和gevent。在生产中,它被托管在Gunicorn上。PyMongo和gevent造成的死锁

我在创建应用程序时创建了一个Connection对象。我有一些后台任务连续运行并每隔几秒执行一次数据库操作。

该应用程序还可以像任何Django应用程序一样提供HTTP请求。

我遇到的问题是以下几点。它只发生在生产环境中,我无法在我的开发环境中重现它。当我让应用程序闲置一段时间(尽管后台任务仍在运行)时,在第一个HTTP请求(实际上是前几个)上,我执行的第一个“find”操作从未完成。 greenlet实际上从不恢复。这会导致前几个HTTP请求超时。

我该如何解决这个问题?这是gevent和/或PyMongo中的错误吗?

+0

您使用的是哪种版本的pymongo? – stbrody

回答

4

我发现问题所在。默认情况下,PyMongo在连接上没有定义网络超时,所以发生的事情是池中的连接断开连接(因为它们暂时不用)。然后,当我尝试重新使用连接并执行“查找”时,连接被检测为死亡(类似15分钟)需要很长时间。当连接被检测为死亡时,“find”调用最终抛出一个AutoReconnectError,并且产生一个新的连接以替换旧的连接。

解决的办法是设置一个小型网络超时(15秒),使呼叫“查找”块greenlet 15秒,提出了一个AutoReconnectError,并且重试时,“发现”,它得到一个新的连接,操作成功。