我当前正在运行的Python Web API在uWSGI + NGINX堆栈上不是多线程的,没有取得很大的成功。由于新的操作需求,我实现了一个新版本,其中包括对外部数据源的多线程请求。但是,当我使用--enable-threads
,在uWSGI下部署此新的多线程构建时,几分钟后,计算机用完了可用线程。
通过使用监视线程计数,我能够将问题与我的外部HTTP请求使用geventhttpclient隔离开来ps -eLf | grep <process id>| wc -l
。我的应用程序中目前有2个工作线程(两个外部请求),因此我注意到,每当我从API中命中/发出请求时,应用程序线程使用计数就会增加2。如果我将geventhttpclient的使用与仅在这些工作线程之一中使用标准python Requests模块,线程计数仅增加1。
注意:我使用HTTPClient.close()关闭每个线程内的连接。
这使我怀疑geventhttpclient创建的新线程在多线程uWSGI应用程序中使用时不会终止。
有一个简单的方法可以解决这个问题吗?在非多线程uWSGI应用程序中,geventhttpclient的性能非常出色,因此我希望继续使用它。
谢谢,让我知道是否能提供更多信息。
将非阻塞程序(geventhttpclient)与阻塞程序(uWSGI线程/进程)混合在一起是完全错误的。这是一条通用规则:即使您的应用程序99%处于非阻止状态,它仍然处于阻止状态。gevent利用堆栈切换来模拟阻塞编程范例这一事实进一步放大了这一点。
这就像协作式多任务处理,由所谓的“ gevent-hub”进行管理。不幸的是,尽管您的greenlets能够发出http请求,但它们永远不会终止,因为一旦请求结束,gevent hub将再也不会运行。
如果要维持geventhttpclient方法,则必须在gevent模式下设置uWSGI,但是需要确保应用程序使用的所有模块和技术都对gevent友好。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句