目前我们有几个Web应用程序(用Django编写)在gunicorn
的默认同步工作程序下运行良好,我们希望使用其gevent
工作程序来获得更好的性能。
众所周知,在使用gevent.monkey.patch_all()
时,有几种具有副作用的操作可能会导致问题:
读取和写入全局变量,包括静态类变量等。在greenlets
之间读取和写入全局变量可能会产生意外结果。
使用C扩展(mysqlclient等)的第三方库。通常,在C扩展中IO /超时可能会阻塞时应该没有问题。但是,如果C扩展存储一些全局状态变量,gevent
可能会导致一些意外行为。我想知道如果在C扩展中使用非阻塞IO或多线程时有任何问题。
现在问题出现了:
如何检查两个或更多greenlets
是否可以读/写任何全局变量?或者一般来说,我们的Web应用程序中是否有任何全局变量编写操作?
如何检查C扩展模块是否与gevent
兼容?
对于第一个问题,我们有一个想法:
在cpython中添加钩子代码。对于每个PyObject
,我们创建两个列表来存储读取或写入对象的greenlets
的ID(或类似内容)。重建cpython并使用实际工作负载运行我们的应用程序进行检查。但实施起来似乎太复杂了。